Skip to content

feat(billing): always-on Free sidebar bar with reset time#2350

Draft
k11kirky wants to merge 1 commit into
mainfrom
posthog-code/usage-sidebar-reset-time
Draft

feat(billing): always-on Free sidebar bar with reset time#2350
k11kirky wants to merge 1 commit into
mainfrom
posthog-code/usage-sidebar-reset-time

Conversation

@k11kirky
Copy link
Copy Markdown
Contributor

@k11kirky k11kirky commented May 25, 2026

Problem

The sidebar usage bar showed no reset time context, and the existing reset countdown used a rolling resets_in_seconds value that drifts between polls. Free-plan users also saw no loading state while usage data was being fetched — the bar simply didn't render.

Changes

  • Added reset_at (absolute UTC timestamp) and billing_period_end fields to the usage schema so the gateway's stable timestamp can be preferred over the drifting resets_in_seconds countdown.
  • Replaced the local formatResetTime in PlanUsageSettings with a shared formatResetTime utility that accepts both reset_at and a fallback seconds value. The function renders human-friendly labels (Resets in 30m, Resets in 4h 30m, Resets May 3 at 2:00 PM PDT, etc.) and prefers the absolute timestamp when available.
  • Updated SidebarUsageBar to show a skeleton loading state while usage data is in flight, rather than rendering nothing. The bar now also displays the reset time label below the progress bar.
  • Refactored useFreeUsage to return { usage, isLoading } so callers can distinguish between "not eligible" and "eligible but still loading."
  • Added error logging in the usage fetch path for both network errors and non-OK HTTP responses.

How did you test this?

Unit tests were added for formatResetTime covering: sub-hour countdowns, hour+minute formatting, hours-only when minutes round to zero, localized date formatting beyond 24 hours, preference of reset_at over fallback seconds, and handling of already-past reset_at values.

Publish to changelog?

no

Free users now see the usage bar with a reset-time line even while
usage is still loading — the previous silent `return null` on
`!usage` is what hid the bar from Free users in session replays.
`useFreeUsage` exposes an `isLoading` flag so `SidebarUsageBar` can
render a skeleton instead of disappearing. Reset time is rendered
via a shared `formatResetTime` helper that prefers the new gateway
`reset_at` ISO timestamp and falls back to `resets_in_seconds`,
producing "Resets in 4h" / "Resets in 4h 30m" / "Resets May 30 at
12:00am PT" depending on the horizon. The duplicated formatter in
`PlanUsageSettings` is replaced with the shared helper. Pro users
still see nothing here — their notifications come via toasts in B2.
Adds a `log.warn` on `fetchUsage` failures so we can see when the
bar is silently hidden by a network/auth error.

Generated-By: PostHog Code
Task-Id: bac06178-1ab1-4000-9a56-1901215bd4af

Generated-By: PostHog Code
Task-Id: bac06178-1ab1-4000-9a56-1901215bd4af
@k11kirky k11kirky force-pushed the posthog-code/usage-sidebar-reset-time branch from a6fca1b to 211250e Compare May 25, 2026 16:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant