Better the Devil You NoSQL

December 10, 2025

Better the Devil You NoSQL

I built my first production systems on DynamoDB. It was fast, forgiving, and felt like freedom. I didn’t have to manage schemas or plan migrations. I could build, deploy, and scale without hesitation. I learned to work with composite keys, single-table design, and denormalized rows because they made sense for the kind of speed I needed.

Over time, that freedom began to feel like a boundary. DynamoDB could handle massive scale, but it made deeper analysis difficult. I could store data, but not easily connect it. NoSQL gave me speed, but it came at the cost of insight.

When I hit that wall, I turned to the wisdom of Nicolas Cage. His work in Ghost Rider came to mind immediately. Like Johnny Blaze, I made a deal for power without understanding the cost. He sold his soul to save his father and lost him moments later. I sold mine to DynamoDB, chasing performance and simplicity without realizing what I was giving up.

Aurora DSQL felt like redemption. It gave me a way to bring structure back without losing agility. Its transactional integrity, IAM-based security, and SQL query power helped me see relationships I had once flattened. Johnny Blaze sought vengeance for deception. I sought balance for my SQL inequities. Aurora DSQL offered a way to face the data I had ignored and use it with clarity and intent.

A Fiery Call: Meeting Aurora DSQL

My work with Aurora DSQL was never about fixing performance or uptime. It was about seeing data clearly again and managing complexity without losing simplicity.

Aurora DSQL brings together what once felt impossible to combine:

  • Serverless and Distributed: Built for horizontal scale and simplified ops.
  • ACID Transactions: Guarantees strong consistency for every operation and uses optimistic concurrency control to prevent unwanted row locks.
  • IAM-Driven Security: Uses temporary tokens instead of static passwords.

Aurora DSQL is more than a database. It challenges the way I think about structure and speed. Like Ghost Rider, it carries three lessons.

  • Revenge: Correcting the ignorance I lived with in my NoSQL years.
  • Justice: Restoring order and predictability to how data behaves.
  • Sacrifice: Trading convenience for a deeper understanding of relationships in the data.

Two Worlds at Odds

DynamoDB taught me how to move fast. It thrives on iteration and clarity of purpose, meaning it’s built for known access patterns and strategic key value lookups. But when I needed to join data, analyze trends, or audit transactions, I had to shift that work to a separate pipeline. That worked until I needed more visibility. Aurora DSQL shifted my mindset. SQL stopped feeling restrictive and started to feel expressive. Global replication, strong consistency, and typed schemas turned chaos into order. This is not a rivalry. DynamoDB taught me how to build quickly. Aurora DSQL taught me how to build wisely. Like Johnny Blaze riding through the night, I am not running from my past. I am powered by it.

It’s time to ride through the flames, face what I feared, and build with purpose.

Accounting for Souls

To understand the strengths and trade-offs of Aurora DSQL, let’s build something fitting for Ghost Rider: a Soul Contract Manager. Even when your work involves collecting souls, you still need good record-keeping. We’ll look at how DynamoDB and Aurora DSQL each handle that responsibility.

DynamoDB – The Ethereal Ledger

DynamoDB uses a single-table design that prizes speed and predictability. Each item is addressed by a precise key, and complex operations require explicit orchestration. Multiple entities are grouped into a single table using composite keys.

Table Structure

PK SK Type Attributes
SOUL#123 CONTRACT#123 Contract status, soul_type, location
SOUL#123 EVENT#2025-11-05T12:00:00Z Event description, timestamp
SOUL#123 LEDGER#2025-11-05T12:00:00Z Ledger amount, description

Access Patterns

  • Get contract: PK = SOUL#123 AND SK = CONTRACT#123
  • List events: PK = SOUL#123 AND begins_with(SK, 'EVENT#')

Example: Capture a Soul

await docClient.transactWrite({
  TransactItems: [
    {
      Put: {
        TableName: "DevilSoulTracker",
        Item: {
          PK: "SOUL#123",
          SK: "EVENT#2025-11-05T12:00:00Z",
          description: "Captured soul in Tulsa",
          timestamp: "2025-11-05T12:00:00Z"
        }
      }
    },
    {
      Put: {
        TableName: "DevilSoulTracker",
        Item: {
          PK: "SOUL#123",
          SK: "LEDGER#2025-11-05T12:00:00Z",
          amount: 2500,
          description: "Processing fee",
          timestamp: "2025-11-05T12:00:00Z"
        }
      }
    }
  ]
});

Every action is explicit. The payoff is speed. The cost is cognitive load and duplication when you need analytics. To ask “Which regions brought in the most balance this week?”, you’d export data to S3 and query with Athena, or pre-aggregate in a stream, or shift to a data warehouse.

Fast and Focused

DynamoDB works like a supernatural ledger that records each soul’s contract on its own page. If you know the key, you can flip directly to it. Reads and writes are nearly instant, which makes DynamoDB perfect for high-speed, single-record operations.

Predictable by Design

The power of this ledger comes from precision. With a well-designed primary key or composite key, you can find exactly what you need every time. It handles direct lookups beautifully, yet struggles with more complex relationships or queries that span multiple records.

Limited Built-In Coordination

When Ghost Rider wants to update a soul’s contract and record several events at once, DynamoDB makes him do the heavy lifting. He has to chain several separate operations, each carefully defined, to make sure everything updates correctly. It gets the job done, but it’s tedious and easy to get wrong.

In Practice

Ghost Rider can log each captured soul in a flash. But when it’s time to update contracts, log events, and process payments in one go, the ledger forces him to piece together multiple steps. It’s fast, but it demands careful choreography.

Aurora DSQL – The Enchanted Grimoire

Aurora DSQL works differently. It thrives on structure and relationships. Instead of flattening everything into one table, you normalize data into related entities.

Schema

CREATE TABLE soul_contracts (
  id UUID PRIMARY KEY,
  soul_name TEXT,
  region TEXT,
  signed_at TIMESTAMP,
  balance NUMERIC
);

CREATE TABLE soul_contract_events (
  id UUID PRIMARY KEY,
  soul_contract_id UUID REFERENCES soul_contracts(id),
  description TEXT,
  occurred_at TIMESTAMP
);

CREATE TABLE soul_ledger (
  id UUID PRIMARY KEY,
  soul_contract_id UUID REFERENCES soul_contracts(id),
  amount NUMERIC,
  transaction_time TIMESTAMP,
  description TEXT
);

Example: Capture a Soul

BEGIN;
INSERT INTO soul_contract_events (id, soul_contract_id, occurred_at, description)
VALUES (gen_random_uuid(), '123', NOW(), 'Captured soul in Tulsa');

INSERT INTO soul_ledger (id, soul_contract_id, amount, transaction_time, description)
VALUES (gen_random_uuid(), '123', 2500, NOW(), 'Processing fee');
COMMIT;

Example: Weekly Summary

SELECT c.region, SUM(l.amount) AS net_power
FROM soul_contracts AS c
JOIN soul_ledger AS l ON l.soul_contract_id = c.id
WHERE l.transaction_time >= NOW() - INTERVAL '7 days'
GROUP BY c.region
ORDER BY net_power DESC;

Everything connects naturally. The same operation that takes two verbose transactions in DynamoDB becomes a single SQL block with ACID guarantees.

Rich, Connected Data

Aurora DSQL feels more like an enchanted grimoire. With a single, powerful SQL query, Ghost Rider can update a soul’s contract, log events, and process fees all in one transaction.

Reliability Through Rules

Each transaction follows strict ACID guarantees, meaning every part of the update succeeds together or not at all. It’s the difference between a loose collection of notes and a single, complete ritual that leaves no room for inconsistency.

More Power, More Effort

That reliability comes with extra steps. Generating IAM tokens, creating secure TLS connections, and managing distributed transactions all take more compute and time. Aurora DSQL trades some speed for precision and consistency.

Designed for Complexity

Aurora DSQL organizes its data by primary keys but supports complex relationships and queries through SQL joins. It rewards careful schema design and disciplined planning. You can’t change structure and data in the same query, so it enforces boundaries that keep things predictable.

In Practice

Ghost Rider opens his grimoire and runs a single, elegant transaction that updates a soul’s contract, logs events, and balances the books. It might take a moment longer to cast, but the result is complete, consistent, and easy to audit later.

Anti-Hero Transformation

Adopting Aurora DSQL was more than a migration. It was a reckoning. What once felt like a curse now feels like a calling.  Like Johnny Blaze in Ghost Rider, I made a deal for power without understanding the cost. DynamoDB gave me speed and freedom, but it also burned away the structure that held deeper knowledge. Moving to Aurora DSQL felt like redemption. It gave me a chance to master multiple database paradigms without being consumed by them.

The Edges of Compatibility

Aurora DSQL wears the face of PostgreSQL, but it is its own creature. Amazon decomposed the Postgres engine into multiple microservices. Each service layer scales independently to provide high availability while also being distributed. The consequence of Amazon’s design choices means that Aurora DSQL is not fully compatible with every Postgres API and feature. Here are some of the current limitations:

  • One Database per Cluster: Each cluster contains a single database named postgres. You organize data through schemas instead of separate databases.
  • Unsupported Features: Triggers, foreign keys, exclusion constraints, and temporary tables are not supported. Relationships and cascading updates must live in your code.
  • Missing Extensions and Commands: Functions that rely on LISTEN/NOTIFY, custom procedural languages, ALTER SYSTEM, TRUNCATE, or SAVEPOINT do not work.
  • Transaction and Session Limits: Each transaction can include only one DDL statement and up to 3,000 changed rows. Sessions expire after one hour.
  • Tool Compatibility: Tools that depend on system catalogs or internal Postgres functions may behave unpredictably. Some drivers need configuration changes to connect correctly.

The Price of Power

Every pact comes with fine print. Aurora DSQL’s serverless design is powerful, but its pricing can turn on you fast. As Corey Quinn put it, it is “a technical marvel with baffling pricing.”

  • Compute Costs: Each query consumes on-demand compute units, so short spikes can raise the bill sharply.
  • I/O and Replication Costs: Every read, write, and global replication event adds a charge. Global reach always carries a price.
  • Scaling Transparency: Automatic scaling removes capacity planning but hides cost patterns. It’s hard to predict what your next transformation will cost.
  • Practical Wisdom: Run a proof of concept. Measure compute and I/O carefully. Treat billing metrics as seriously as latency metrics.

Praise Cage!

Johnny Blaze didn’t escape his curse; he learned to ride with it. The same is true for any developer learning to balance NoSQL freedom with SQL discipline. DynamoDB lights the fire. Aurora DSQL shapes it into purpose. True mastery isn’t just about power; it’s about control, patience, and intent. Open your hearts to the possibilities of using multiple database paradigms!

So raise your schema, brothers and sisters of the stack. Keep your IAM tokens short-lived and your transactions clean. When the queries get hot and the costs climb higher than expected, whisper the sacred words: Praise Cage!

https://github.com/pchinjr/devil-you-nosql

CFP

Better the Devil You NoSQL - Demo Walkthrough

https://www.duckbillhq.com/blog/aurora-dsql-a-technical-marvel-with-a-pricing-randomizer/

Serverless Handbook
Access free book

The dream team

At Serverless Guru, we're a collective of proactive solution finders. We prioritize genuineness, forward-thinking vision, and above all, we commit to diligently serving our members each and every day.

See open positions

Looking for skilled architects & developers?

Join businesses around the globe that trust our services. Let's start your serverless journey. Get in touch today!
Ryan Jones
Founder
Book a meeting
arrow
Founder
Eduardo Marcos
Chief Technology Officer
Chief Technology Officer
Book a meeting
arrow

Join the Community

Gather, share, and learn about AWS and serverless with enthusiasts worldwide in our open and free community.