Rails API Mode vs Full Rails — When Lightweight Actually Makes Sense
by Eric Hanson, Backend Developer at Clean Systems Consulting
The "we don't need views" trap
Your new project is an API consumed by a React frontend. Someone on the team suggests Rails API mode because "we don't need the view layer." That logic sounds reasonable. It is usually wrong. Here is why, and the narrow set of cases where it is actually right.
What API mode actually removes
Running rails new my_app --api generates a slimmer stack than full Rails. The middleware stack drops from about 22 middlewares to 11. You lose ActionView, ActionMailer (not loaded by default, though you can add it), cookie-based sessions, flash messages, and browser security middleware like ActionDispatch::Flash.
What you gain is marginally faster request processing and a smaller memory footprint — in practice, around 10-15% less memory per worker on a comparable workload, based on profiling I have done on apps with ~200 RPS. That is real, but not dramatic.
# API mode application controller — note the different base class
class ApplicationController < ActionController::API
include ActionController::HttpAuthentication::Token::ControllerMethods
before_action :authenticate_token
private
def authenticate_token
authenticate_or_request_with_http_token do |token, _options|
@current_user = User.find_by(api_token: token)
end
end
end
The slimmer middleware stack also means you cannot use ActionController::Cookies or ActionController::Sessions without explicitly re-adding them. This matters more than people anticipate.
The features you will miss
Three months into an API-mode project, teams almost always rediscover they need some of these:
Admin interfaces: You shipped the API. Now you need an admin panel to manage data. Full Rails would have given you a clean path to building it with ERB views or integrating Administrate/Avo. In API mode, you are now adding a whole separate admin frontend or re-adding the view layer to your API app — neither is clean.
Action Mailer: The --api flag does not wire up Action Mailer by default. You add it manually in about five minutes, so this is not a dealbreaker, but it is one of several small things that erodes the claimed simplicity.
Authentication flows with sessions: Token-based auth works cleanly in API mode. If you later need OAuth2 callback flows, magic link emails with session state, or any server-rendered auth page (think: OAuth consent screens), you are bolting on middleware you removed intentionally.
Rack middleware for browser security: CSRF protection, same-origin policy enforcement, and secure cookie handling are not relevant for a pure JSON API with token auth. But if you ever serve a mix of API and browser traffic — which most apps eventually do — you will retrofit these.
When API mode is genuinely the right call
Use it when all three of these are true:
-
The application is a dedicated backend service consumed exclusively by clients that handle their own rendering (mobile apps, SPAs, other services). There is no admin UI, no server-rendered views, no mixed traffic.
-
You are running multiple Rails apps in a microservices or service-oriented architecture and this service is purely a data/business logic layer. The view infrastructure lives elsewhere.
-
Memory density matters at your scale. If you are running 50+ Puma workers per host and need to pack more in, the 10-15% memory savings add up.
# Creating a true API-only service
rails new payments-service \
--api \
--skip-action-mailer \
--skip-action-mailbox \
--skip-action-text \
--skip-active-storage \
--database=postgresql
That is a genuinely lean service — 11 middlewares, no asset pipeline, no mailer configuration, focused entirely on processing and returning JSON.
The case for staying on full Rails
Full Rails with render json: is not meaningfully heavier for most applications. The view layer does not add overhead on JSON requests — it is simply not invoked. The middleware you "save" in API mode includes security defaults that you will likely want or re-add.
More importantly, full Rails keeps your options open. Adding an admin interface, an email template, or a server-rendered error page is zero friction. The transition from full Rails to a separate admin app later is a product decision you can make when you actually need to. Making it now, preemptively, usually means making it wrong.
The practical rule
If your team is debating API mode vs full Rails for a new service: pick full Rails by default. Switch to API mode if and only if the service is a true internal component with no browser-facing surface area and you have a specific reason to care about the memory difference. Otherwise you are trading future flexibility for a configuration that sounds leaner but does not measurably perform better for your use case.