Why Fast Systems Depend on What They Refuse to Change

Kai Nguyen

Hatched by Kai Nguyen

Aug 01, 2026

9 min read

87%

0

The hidden tradeoff behind speed

What makes a system fast: doing less work, or knowing exactly what can never change?

That question sits underneath two ideas that seem unrelated at first. One is about objects in memory, where some values can change and others cannot. The other is about SQL performance, where some queries can use indexes efficiently and others force the database to grind through far more data than necessary. But both are really about the same deeper problem: speed comes from preserving structure.

A system gets sluggish when it has to keep reinterpreting everything from scratch. A database that cannot use an index has to scan. A program that keeps mutating shared values has to keep checking what still remains valid. In both cases, the cost is not just extra work. The cost is uncertainty.

The fastest systems are not the ones that do the most, but the ones that protect the assumptions that let them do less.

That idea matters far beyond Python and SQL. It is a design principle for software, for data, and for thinking itself.

Mutability and SARGability are the same kind of problem

At first glance, mutability is a language concept and SARGability is a query tuning concept. Yet both are about whether a system can rely on stable boundaries.

An immutable object gives you a promise: once created, its value will not change. That promise makes the object easier to reason about, safer to share, and easier to cache. A string in Python is a classic example. If you pass it around, you do not have to wonder whether some other part of the program silently altered it.

A SARGable query gives the database a similar promise. It says, in effect: the filter condition is written in a form that can take advantage of the index structure already in place. If the database can seek directly to the relevant rows, it avoids a full scan. If it cannot, it has to inspect far more data than necessary.

The resemblance is not superficial. In both cases, performance depends on whether the system can trust a stable representation.

Think of an index as a map and a mutable data structure as a town where streets keep rearranging themselves. A map works only if streets stay where they were when the map was drawn. Likewise, an index helps only if the query preserves the shape the optimizer expects. If you wrap an indexed column in arithmetic, a function, or a negation, you often force the system to stop using the shortcut and start looking line by line.

This is why statements like these matter:

  • Avoid arithmetic on indexed columns in the WHERE clause.
  • Avoid leading wildcards when you want an index to help.
  • Filter early.
  • Use appropriate indexes.
  • Avoid unnecessary calculations, sorting, and grouping.

All of them are variations on one theme: do not destroy the structure that enables efficient navigation.

Why hiding structure is expensive

The real enemy of performance is not work itself, but work that could have been avoided if the system had been allowed to preserve its shape.

When a value is immutable, the language can make stronger guarantees. It can safely reuse the value, share it between callers, and avoid defensive copying. When a query is SARGable, the database can avoid brute force and use the index to jump directly where it needs to go. In both cases, the system is exploiting a stable surface area.

The opposite creates hidden costs. Mutable objects create coordination overhead. Every consumer must ask: has this changed? Will it change while I am using it? Do I need to copy it first? Query expressions that defeat indexes create search overhead. The database must inspect records one by one because the shortcut no longer applies.

Here is the deeper pattern: a system pays dearly whenever it cannot collapse many possibilities into a small set of trusted assumptions.

A concrete example makes this easier to see. Suppose you have a table of orders with an index on created_at. A query like this is friendly to the engine:

SELECT *
FROM orders
WHERE created_at >= '2026-01-01'

The database can locate the starting point and walk forward. But if you write:

SELECT *
FROM orders
WHERE DATE(created_at) = '2026-01-01'

you may have turned a direct search into a computation over every row. The meaning is similar, but the shape is not. The second version hides the column inside a function, and that concealment blocks the shortcut.

Now compare that to mutable state in code. If one function can change an object after another function has already reasoned about it, then the second function loses its shortcut. It can no longer trust the object’s shape or contents. It must recheck, copy, synchronize, or defend itself.

Performance is often just trust, made measurable.

The deep design choice: preserve meaning or preserve convenience

A useful mental model is to distinguish between semantic stability and syntactic convenience.

Semantic stability means the system can preserve what something is. The data remains the same. The query condition still matches the indexable form. The object keeps its identity and value. Syntactic convenience means the code is easier to write in the moment, even if it makes the system harder to optimize later.

Many slow systems are not slow because they are badly built. They are slow because they chose convenience at the wrong layer.

For example, it is tempting to write a query using a function because it looks clean:

WHERE LOWER(email) = LOWER('[email protected]')

But that may prevent an index from helping unless you have planned for it. A more index friendly design might store a normalized version of the field or use a functional index. In other words, you do not fight the engine by asking it to do cleverness at runtime when you could have prepared the structure ahead of time.

The same applies in code. Mutable structures are not bad in themselves. They are powerful when local modification is exactly what you need. But if you allow mutability to spread everywhere, you force every part of the system to live inside constant uncertainty. Immutability is not about dogma. It is about choosing where change is allowed so the rest of the system can become simpler and faster.

This suggests a broader principle:

Constrain change at the edges so the core can stay indexable.

That phrase works for both data systems and software architecture. If the boundaries are stable, the internals can optimize aggressively. If everything is allowed to mutate or be transformed on the fly, the system loses its leverage.

A practical framework: ask what the optimizer needs to believe

Whether you are writing code or SQL, the most useful question is not merely “Is this correct?” It is: What must the system believe in order to be efficient?

For Python objects, the answer may include:

  1. This value will not unexpectedly change.
  2. This object can be shared safely.
  3. This reference can be passed without defensive copying.

For SQL queries, the answer may include:

  1. The filter can be matched to an index.
  2. The engine can narrow the candidate set early.
  3. The database can avoid scanning, sorting, or grouping unnecessary rows.

Once you start thinking this way, optimization stops being a bag of tricks and becomes a discipline of preserving useful assumptions.

Consider a few practical transformations:

  • Instead of applying a function to every row in the WHERE clause, store data in the form you actually query.
  • Instead of using leading wildcards like %abc, design searchable prefixes or use a search structure built for that pattern.
  • Instead of mutating shared objects in many places, create new values when the state really changes.
  • Instead of sorting or grouping more data than you need, reduce the result set early.

These are not isolated tips. They are all attempts to keep the system from losing track of structure.

A good optimizer, whether human or machine, likes boundaries. Boundaries reduce possibility space. They turn a large search into a smaller one. They make the next decision cheaper because they have already ruled out most of the world.

The broader lesson: efficiency is a form of disciplined restraint

We often imagine performance as an engineering contest, a race to squeeze more out of hardware or algorithms. But many of the biggest wins come from refusal, not effort. Refusal to mutate too freely. Refusal to wrap a searchable column in unnecessary computation. Refusal to let convenience erase structure.

This is why immutable objects and SARGable queries feel like distant relatives. Both encode a philosophy of disciplined restraint. They do not eliminate flexibility. They place it in the right location. The system gets freedom where change is intended and stability where performance depends on prediction.

There is also a psychological lesson here. Good designers do not ask only, “How can I make this work?” They ask, “What am I asking the system to stop knowing?” Every time you obscure a pattern, you reduce the engine’s ability to help you. Every time you introduce uncontrolled mutability, you reduce the program’s ability to trust itself.

That is why the most elegant systems often look boring from the outside. They are full of stable values, predictable paths, and query shapes that the engine can understand. Their simplicity is not naive. It is engineered.

Key Takeaways

  1. Preserve structure if you want speed. Whether in memory or in a database, stable shape lets systems avoid unnecessary work.
  2. Treat mutability as a local tool, not a global default. Shared change creates coordination costs that ripple outward.
  3. Write queries so the optimizer can see the index. Avoid wrapping indexed columns in functions, arithmetic, or leading wildcards when possible.
  4. Ask what assumptions your system needs in order to be efficient. Optimization begins with protecting those assumptions.
  5. Move complexity to design time, not runtime. Normalize data, choose the right indexes, and define stable values early.

Conclusion: the fastest path is the one that stays legible

We tend to think speed comes from doing things faster. More CPU, better indexing, cleaner code, smarter algorithms. But a deeper truth runs through both programming and databases: speed comes from remaining legible to the system doing the work.

Immutable values are legible because they do not surprise you. SARGable queries are legible because they preserve the form an index can understand. In both cases, the system becomes fast not by guessing harder, but by needing to guess less.

The next time something feels slow, do not ask only what computation is happening. Ask what structure has been hidden, broken, or made uncertain. Often the path to speed is not more motion. It is fewer surprises.

Sources

← Back to Library

Hatch New Ideas with Glasp AI 🐣

Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)

Start Hatching 🐣