Repository navigation
feat(sequences): durable test-send limits and shared-mailbox quota for tests - #120
Merged
Merged
Conversation
…r tests Test sends were capped at 50 recipients per team per hour in process memory, which reset on restart and multiplied with replicas, and tests through an organization's shared mailbox skipped its quota. - Redis sliding windows: 100 per team per 24h, 50 per 3h, 20 per email per 24h (configurable), all or nothing, with retry-after. - Tests through a shared mailbox are charged to the grant's quota up front and refunded if they don't go out. - 429 for the new codes, friendly web messages, PostHog event when limited, docs, contract and MCP descriptions.
The chip field accepted any number and only disabled Send. It now stops adding at five (typed or pasted), hides the input when full and says why.
Each send stores (or reuses) an immutable copy of the email's subject and content, and its view-in-browser link carries that version's public id, so editing a running sequence's email no longer changes what earlier recipients and test links show. Older links keep showing current content. A sent broadcast's title (its subject) is now locked like its content.
Web versions show the content that was sent
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Test sends follow the industry pattern (Mailchimp, Klaviyo, Omnisend): any address is allowed, every recipient counts once, and there's a stored cap per account. Tests through an organization's shared mailbox now draw on that mailbox's quota.
Before
Map). It reset on restart or deploy and multiplied with API replicas.Now
sequences/test-send-limits.ts), one atomic Lua script per test:test_send_limit_reachedandtest_send_email_limit_reached, each withretryAfter.TEST_SEND_DAILY_LIMIT,TEST_SEND_BURST_LIMIT,TEST_SEND_BURST_HOURSandTEST_SEND_EMAIL_DAILY_LIMIT.chargeOrganizationQuotaForTestscounts tests as accepted usage on the grant and organization day/month buckets, all or nothing.refundOrganizationQuotaForTestsreturns any tests that didn't go out.reserveOrganizationQuota(lockBucketsWithRoom,lockActiveGrant), so the behaviour is the same. Tests through the team's own ESP aren't charged..env.exampleare updated.sequence_email_test_limitedevent recordserror_code,kind,email_idandrecipients_count.Tests
test-send-limits.test.tsagainst real Redis: the per-email cap is all or nothing, the team burst spans emails, the rolling day is enforced, retry-after is sane, and the defaults are correct.organization/queries.test.ts: charging tests through a shared mailbox (all or nothing at the grant's daily limit), then a refund.test-send.test.ts: each deliverable recipient counts once (deduped and case-insensitive), and nothing is sent past the limit.