Key details

  1. Buttondown says its production database fell from about 2TB to 750GB after the work.
  2. The removed data paths were APIRequest, RawEmailEvent and EmailEvent.
  3. API request payload retention is now narrower, with long-lived request/response storage tied more closely to idempotency-key use.
  4. Raw ESP webhook payloads now flow through Buttondown’s shared asynchronous-actions system instead of a dedicated raw-event table.
  5. Buttondown backfilled external events to 2019 before removing the old EmailEvent model.
  6. The company says more than half of database storage and storage cost was eliminated.

What builders should take away

  1. Treat retention as a product and operational decision, not a default of 'forever.'
  2. Look for intermediate tables whose original consumers have migrated to a newer source of truth.
  3. High-volume debugging data can deserve a shorter default lifetime than transactional business records.
  4. Do the migration work before the deletion: inventory readers and writers, backfill replacement state and prove the new path is load-bearing.
  5. Measure storage cost by data class so architectural cleanup can compete fairly with feature work.

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.

What to watch next

  • Whether Buttondown publishes a follow-up with actual database latency or compute improvements after the storage reduction.
  • Whether narrower API request retention creates support or debugging trade-offs for customers without idempotency keys.
  • Further Buttondown work consolidating queues, event processing or database infrastructure.

Still unclear

  • The 2TB, 750GB and cost figures are company-reported rather than independently measured.
  • Buttondown says the database became faster but does not publish before-and-after latency or compute benchmarks.
  • The post describes storage cost as more than halved without publishing the underlying invoice amounts.

Sources

Direct reading behind this dossier.

1 sources
The Great Pruning
Buttondown engineering post

Primary engineering account for the three removed tables, migration approach, 2TB-to-750GB reduction and storage-cost claim.

Discussion

Discussion is reader-contributed. Comments are not part of the BTN dossier or its editorial evidence.

0 visible comments

Join the discussion

Keep comments useful and relevant. Reader contributions may be moderated and are not BTN editorial evidence.

Sign in to comment