Dev News Daily ENDE

Rails loads a JSON schema cache 22x faster than YAML on a 944-table app

This week's Rails changelog carries two entries worth acting on. Active Record can now dump and load its schema cache as JSON: point schema_cache_path at a file ending in .json and it stops using YAML or Marshal. On a production application with 944 tables, the Rails post reports JSON loading about 22x faster than YAML.

The second is bin/rails herb:check, a rake task that compiles every HTML+ERB template through Herb using the same resolvers the runtime lookup uses — so variants, locales and engine view paths are covered. Templates it rejects are listed with path and error, and the task exits non-zero when any fail.

Rails loads a JSON schema cache 22x faster than YAML on a 944-table app
Rails loads a JSON schema cache 22x faster than YAML on a 944-table app — Dev News Daily

What it means

The schema cache change is a boot-time number, which makes it a deploy-time number: every process start, every container, every autoscaling event. If your app has hundreds of tables and you have ever watched a rolling deploy crawl, this is a one-line configuration change with a measured result — and the measurement is theirs, on their app, so run it on yours before quoting it.

herb:check matters for a different reason: a template error is the classic failure that unit tests do not catch and production does. Exiting non-zero means it belongs in CI, not in a developer's terminal. Add it next to your linter and it converts a class of 500 into a red build.

Where the 22x actually comes from

YAML is a general-purpose format with anchors, aliases, custom tags and type coercion; a parser has to consider all of it. JSON has six value types and no extension points, and every runtime ships a parser that has been optimised for a decade. The schema cache is a large, boringly regular data structure — exactly the shape where that difference stops being academic.

Marshal is faster still, and it is also version-locked: a cache dumped by one Ruby cannot be trusted by another. JSON removes that constraint, which is why this is interesting for containers, where the image and the runtime are not upgraded on the same day.

What to measure before you switch. Time rails runner "ActiveRecord::Base .connection.schema_cache" cold, on an image with the cache present, and again after pointing schema_cache_path at a .json file. If your app has forty tables, expect the difference to be invisible; the number in the announcement comes from 944 tables, and the gain scales with the size of the schema, not with your traffic.