Case study · Stack

How 37signals runs Basecamp and HEY on Rails and its own servers

37signals makes Basecamp and the HEY email service with a small team, and it is the company behind Ruby on Rails. Its stack is Rails with Hotwire and MySQL, deployed with its own tool, Kamal, onto servers it owns, after leaving AWS between 2023 and 2025.
Copy this stackbasecamp.com Project management and email software (Basecamp and HEY) · United States · founded 1999

Basecamp (37signals)'s stack

Open in the stack builder

UI library

  • Hotwirehotwired.dev

    Builds the interface with Turbo and Stimulus by sending HTML from the server.

    Why: Sending HTML instead of JSON keeps rendering on the server, loads fast and keeps development simple.

Hosting

  • Kamaldev.37signals.com

    In-house tool that deploys the apps to the company's own servers.

    Why: It was built for their exact need: rolling one app out across many hosts behind a load balancer.

  • Kamal Proxydev.37signals.com

    Load balancer in front of apps like Fizzy.

  • Dellworld.hey.com

    Servers the company bought to run its apps after leaving AWS.

    Why: The cloud's promised savings never came and the team never shrank, so owning hardware was cheaper.

  • Deftdev.37signals.com

    Leases the rack space, power and bandwidth in the data centers where the servers live.

Database

  • MySQLdev.37signals.com

    Standard database for the company's SaaS apps.

    Why: The team knows it well, it has proven performance and database servers scale separately from app servers.

  • SQLitedev.37signals.com

    Database of the self-hosted ONCE products, with one file per customer.

Data fetching

  • Solid Cachedev.37signals.com

    Database-backed cache for Basecamp and HEY, replacing Redis in Basecamp.

    Why: It gives a much larger cache for a fraction of the cost of memory caches like Redis.

  • Solid Queuedev.37signals.com

    Database-backed background job queue for HEY, replacing Resque and Redis.

    Why: They wanted background jobs out of the box instead of managing the seven gems Resque needed.

Backend framework

  • Ruby on Railsdev.37signals.com

    Framework behind Basecamp, HEY and the company's other apps.

File storage

  • Pure Storagedev.37signals.com

    FlashBlade arrays with an S3-compatible API that replaced AWS S3 for about 10 PB of files.

    Why: Flash cost about the same as spinning disks and was much faster, which mattered for the big copy.

How they built it

Rails, and HTML instead of JSON

Basecamp and HEY are Ruby on Rails apps. Instead of a heavy single-page app talking to a JSON API, 37signals built Hotwire: the server sends ready HTML, Turbo swaps it into the page, and Stimulus adds small bits of JavaScript where needed. Hotwire was made to power HEY and is now open source.

The point is to keep rendering on the server, get fast first loads and keep development simple, without giving up the feel of a single-page app.

Sources:hotwired.dev dev.37signals.com

The cloud bill that started the exit

In 2022, 37signals spent $3.2 million on AWS. S3 alone cost about $908,000 for roughly 8 PB of files, and HEY's production setup, with EKS, Aurora MySQL and ElastiCache, came to more than $1 million. The company said the promised cloud savings never showed up and the team never got smaller.

In 2023 it moved Basecamp, HEY and five older apps off AWS onto about $700,000 of Dell servers, in data centers where Deft leases the rack space, power and bandwidth. No one new was hired for it. The cloud bill fell to $1.3 million in 2024, and the company now expects more than $10 million in savings over five years.

Sources:dev.37signals.com basecamp.com world.hey.com

Kamal: deploying without Kubernetes

Leaving the cloud meant they needed a simple way to ship apps to their own machines. 37signals built Kamal, a deploy tool for apps running on virtual machines or bare metal. Version 1 covered their own case, one app rolled out across many hosts behind a load balancer, and version 2 also handles several apps on a single server.

HEY was the first app on Kamal 2, with faster deploys and simpler config. Kamal Proxy, also made in-house, now acts as the load balancer in front of apps like Fizzy.

Sources:dev.37signals.com dev.37signals.com

The last step: 10 PB off S3

Files were the last thing left on AWS, at close to $1.5 million a year. 37signals racked Pure Storage arrays in its two main data centers, 18 PB combined and replicated a thousand miles apart, and their S3-compatible API made the switch on the app side fairly easy. AWS waived the data transfer fees for a full exit.

The copy of about 10 PB, roughly 5 billion objects, finished in under 10 days. The team picked flash-based FlashBlade because it cost about the same as spinning disks and was much faster.

Sources:world.hey.com dev.37signals.com

Putting the database to work instead of Redis

37signals has been moving jobs that used to need Redis into the SQL database. Solid Cache stores Basecamp's cache on disk: reads are a bit slower than Redis, but the cache is 6 times bigger, costs 80% less, and the 95th percentile request time fell from 375 ms to 225 ms. Solid Queue replaced Resque and Redis for background jobs in HEY.

The team also tried a SQLite database per customer for its new app, Fizzy, and went back to MySQL, its standard for SaaS apps, because of familiarity, proven speed and database servers that scale on their own.

Sources:dev.37signals.com dev.37signals.com dev.37signals.com

Also detected on their website

Found on the homepage with the open Wappalyzer rules (HTML, scripts and headers). It shows what runs in the browser, not the whole backend.

  • Bootstrap
  • Cloudflare
  • Stimulus