Sitemap

The Day I Learned Two Brutal Backend Lessons the Hard Way

2 min readJun 27, 2026

--

Most backend bugs don’t announce themselves loudly. They quietly sit in your system… until one day they don’t.

I learned two of these lessons early on one about security, and one about performance. Both are simple in concept, but extremely common in real systems.

1. “How did he update someone else’s ticket?”

We had a basic ticketing system.

Two users:

  • Ramesh → working on Ticket A
  • Suresh → working on Ticket B

Everything seemed fine… until Ramesh somehow updated Suresh’s ticket.

At first glance, it felt like a bug in the frontend.

It wasn’t.

The issue was simple:
The API trusted the ticket ID coming from the request without properly verifying ownership.

What went wrong?

We were doing this:

“If request is valid, update ticket.”

But we forgot the real question:

“Is this user allowed to update this specific ticket?”

The fix

Never trust client input for access control.

The backend must:

  • Extract user identity from the auth token
  • Fetch the resource (ticket)
  • Validate ownership or permissions
  • Only then allow the update

Because:

Authentication tells you who the user is
Authorization tells you
what they can touch

And missing authorization is one of the most common real-world security flaws.

2. The silent killer: N+1 queries

Later, another issue appeared — but this one wasn’t about security.

Get Ashish Bhardwaj’s stories in your inbox

Join Medium for free to get updates from this writer.

It was about performance.

A simple API was fetching tickets and their assigned users.

It worked fine in testing.

But in production, it started slowing down.

What was happening?

Instead of:

  • 1 query to fetch tickets
  • 1 query to fetch related users

We were doing:

1 query + N queries (for each ticket)

This is the classic N+1 query problem.

At small scale? You won’t notice it.
At production scale? It can bring systems to their knees.

The fix

We optimized data fetching by:

  • Using JOINs
  • Applying eager loading
  • Fetching related data in batches instead of per-record calls

The goal was simple:

Reduce database round trips as much as possible.

Final takeaway

These two issues taught me something important:

  • Security bugs happen when we trust the client too much
  • Performance bugs happen when we underestimate scale

Both are silent at first. Both become expensive later.

And both are completely avoidable if you get the fundamentals right.

--

--