The method
How It Works
Detailed explanations of PepCycle's product-type-aware consumption, concentration and syringe math where applicable, forecasts, schedules, and notification timing.
Use the public calculator to run single-vial and fixed-ratio blend calculations without signing in. For quick answers see the FAQ. For a step-by-step walkthrough see the User Guide.
Concentration & syringe math
This section applies to injected products. Lyophilized products use BAC water and reconstitution math. Oil-based products track remaining ml separately from active ingredient mass and convert a scheduled dose through mg/ml into injection volume and syringe marks. Oral products convert the dose through mg per tablet and track remaining tablets without BAC, reconstitution, or syringe calculations.
Step 1 — Calculate concentration
When you add BAC water to a vial, you record the volume added. Combined with the total vial size, this gives the concentration:
(result is in the same unit as vial_size, per ml)
Step 2 — Amount per syringe mark
Insulin syringes are calibrated in IU marks. U-100 syringes have 100 marks per ml; U-40 syringes have 40 marks per ml. The amount of peptide per single mark is:
Step 3 — Marks needed for your dose
If the dose unit differs from the vial unit (e.g. dose in mcg, vial in mg), the app converts the dose to the vial unit before dividing.
When a current vial remainder is used before a newly reconstituted vial, syringe math is calculated separately for each vial concentration and then summed. For example, 10 marks from the current vial plus 3 marks from the new vial is shown as 13 syringe units total.
The upcoming-dose preview applies the same calculation in chronological order. Once a projected dose empties the current vial, later preview cards use the prepared vial's concentration instead of repeating the old vial split.
Changing your syringe type
In Settings → Syringe, you can select U-100 (100 marks/ml), U-40 (40 marks/ml), or enter custom values. The ticks_per_ml value changes the per_mark calculation and therefore all IU readings throughout the app and in notification messages.
Dose calculations
Storing doses in mcg
Every dose is stored internally in mcg (micrograms) regardless of the unit you enter. The conversion is simple:
dose_mcg = dose_amount (if unit is mcg or IU)
IU is stored as-is because there is no universal mcg↔IU conversion — it is peptide-specific and outside the scope of this app.
Deducting from vial remaining amount
When a dose is logged, the deduction from the vial is made in the vial's own unit:
new_remaining = remaining - deduction
New remaining: 4.75 − 0.25 = 4.5 mg
Vial depletion & reconstitution forecast
Each product card shows how many doses remain in the current vial and estimates when a new reconstitution will be needed, based on the active protocol schedule.
Doses remaining
Days until depletion
The schedule frequency (doses per day) is calculated from the schedule type:
- Daily → 1 dose/day
- Every N days → 1 / N doses/day
- Specific weekdays → count of selected weekdays / 7
18 / (1/3) = 18 × 3 = 54 days
Reconstitution forecast states
The forecast line on the product card uses urgency levels based on the days until depletion:
- Normal — more than 7 days remaining; shows target date
- Warning — 7 days or fewer; shown in amber
- Urgent — empty or less than one full dose; shown in red
- Covers protocol — for finite protocols where the vial is sufficient through the protocol end date
- No active schedule — no protocol; only dose count is shown, no timing estimate
Finite protocol: covers-through check
If a protocol has an end date, the app first checks whether the current vial is sufficient to reach that date before computing a reconstitution deadline:
if days_until_empty ≥ days_until_end → "Covers protocol through [date]"
36 > 18 → "Covers protocol through [end date]"
Inventory forecasting
Syringe inventory
If a syringe item is linked to a protocol (one syringe deducted per dose), the forecast for that item uses the same doses_per_week from the schedule:
BAC water inventory
BAC water is consumed in reconstitution events, not per dose. PepCycle estimates future reconstitution events from your active protocols, current vial remaining amount, and BAC water volume per vial, then compares the projected coverage to your inventory thresholds.
If there is not enough schedule or vial information to estimate future reconstitutions, the app falls back to the current remaining quantity and shows that coverage is unknown.
Low-stock threshold
Lyophilized products, Oil-based products, Oral products, BAC water, and syringes each use independent configurable coverage thresholds:
When no coverage forecast can be computed — an item with no linked schedule — it is not marked low on quantity alone; it only alerts once it runs out entirely. In-app alerts auto-resolve once stock or coverage returns above the alert threshold.
Schedule mechanics & next_due
Every protocol has a next_due timestamp — the exact date and time the next dose is scheduled. When a dose is logged (manually or via auto-log), next_due advances to the next occurrence.
Daily schedule
(or later today if time_of_day hasn't passed yet)
Every N days schedule
Specific weekdays schedule
The app scans forward up to 14 days from the current time to find the next occurrence on a matching weekday at the configured time.
Dashboard seven-day window
The Dashboard generates every active occurrence from the start of today through the end of the sixth day after today. Cycling off-days are excluded, titration is calculated for each occurrence date, and prepared-vial/remainder projections are simulated in chronological order.
The UI groups those occurrences by day. Expanding a day reveals the complete set for that date; collapsed rows still show the dose count so the app never silently hides extra schedules.
Notification timing logic
The notification worker runs on a 5-minute cycle. Each cycle it checks all active protocols and fires a notification if the current time falls within the delivery window for that protocol.
Delivery window
window_end = next_due (or next_due + 10 min when advance = 0)
The worker fires if: window_start ≤ now ≤ window_end.
Deduplication
Each protocol+slot pair creates a notification_reminder record. Once a notification is sent, sent_at or telegram_sent_atis stamped on that record. The worker skips the slot on subsequent cycles to prevent duplicate delivery.
Telegram vs push independence
Telegram delivery and push delivery use separate sent_at fields. This means a protocol can receive both channels independently without one blocking the other. The Telegram worker runs in a Supabase Edge Function; the push worker runs in the Cloudflare Worker cron handler.
Auto-logging logic
When "Auto-log doses" is enabled, the app logs a dose automatically after a successful notification delivery. The logic applied:
- Day-level duplicate check — if a dose (manual or auto-logged) already exists for this protocol today, skip.
- Fetch peptide vial data — needed for the syringe unit calculation to store with the dose.
- Insert dose record — using the protocol's configured dose_amount, dose_unit, and calculated syringe units.
- Deduct from vial — the current vial is decremented first; if a prepared vial is needed, only the missing amount is deducted from that vial.
- Advance next_due — advanced by the schedule interval in milliseconds from the current time, preserving your local time-of-day across timezones.
- Deduct syringe inventory — if a syringe item is linked to the protocol.
- Stamp reminder — the notification_reminder record is marked with auto_logged_at and channel.
- Log notification event — an auto_logged event is recorded in notification history.
Skip dose behavior
Skipping N doses advances next_due by N occurrences of the schedule pattern without logging any doses or decrementing the vial. A skip event is recorded in History.
next_due after skipping
For "every N days" protocols, skipping 2 doses advances next_due by 2×N days. For weekday protocols, it advances to the 2nd next matching weekday.
What is unchanged
- Vial remaining amount (no dose was administered)
- Protocol active status
- Dose history (no dose entry is created)