What changed
Buttondown documented the removal of its three largest database tables: APIRequest, RawEmailEvent and EmailEvent. The platform had accumulated large volumes of API request/response records and email-delivery event data, while later architecture had made parts of that storage redundant. Buttondown changed what API payloads it retains, folded raw email-event ingestion into its asynchronous-actions system and completed a migration from the old EmailEvent model to its external-event model. The company says those removals reduced its database from about 2TB to 750GB and removed more than half of its database storage cost.
Why it matters
Small SaaS teams often accumulate cost through data that once had a clear operational purpose but is no longer on the critical path. Buttondown’s example is useful because the saving did not come from negotiating a cloud discount or moving to a cheaper hyperscaler product. It came from reducing retention, removing duplicate intermediate representations and simplifying the event pipeline. The trade-off is that historical debugging and compatibility requirements must be understood before deletion; Buttondown spent time migrating readers and writers and backfilling replacement events before removing the old tables.
API debugging data had become permanent by accident
Buttondown logged every API request so users and support could inspect failures, including redacted request and response data. The original retention period was effectively infinite. Even after the company moved toward a roughly 90-day TTL, the constantly hot table made deletion difficult. It ultimately dropped some foreign-key constraints and changed the default so large request/response payloads are retained only when the request uses an idempotency key, targeting the cohort most likely to need long-lived debugging data.
Raw email events moved into an existing queueing system
Buttondown receives millions of webhook events each day from email service providers. It had used a RawEmailEvent table as a producer/consumer buffer. After replacing Redis with a homegrown Postgres asynchronous-actions system, the platform no longer needed the dedicated raw-event model: the webhook consumer can create an asynchronous action containing the payload and let the shared retention/archiving machinery handle it.
A second event model had become a redundant halfway house
The older EmailEvent table represented deliveries, bounces, clicks, opens and other normalized events. Over time Buttondown’s external-event model became the load-bearing event bus for webhooks, automations and analytics. The company gradually moved readers and writers, backfilled missing external events to 2019 and then removed EmailEvent entirely rather than preserving a high-traffic transformation layer indefinitely.
Deleting data changed the cost base materially
Buttondown says the three removals reduced database size from roughly 2TB to 750GB. That is a 62.5% reduction in stored data, and the company says more than half of its database storage cost disappeared with it. It also describes the smaller database as faster, although it does not publish a benchmark quantifying the performance improvement.
The pattern is architectural, not Buttondown-specific
The broader lesson is to periodically re-audit tables created for debugging, ingestion and compatibility. High-volume SaaS systems can keep storing intermediate data long after a newer source of truth exists. A safe deletion project requires identifying consumers, changing write paths, backfilling durable replacements and only then removing the old model.