Skip to main content

Command Palette

Search for a command to run...

The Day a “Small” Data Type Choice Slowed Down Everything

A production-focused deep dive into MySQL data types, covering numeric types, DECIMAL vs FLOAT, CHAR vs VARCHAR, and DATETIME vs TIMESTAMP with real-world debugging insights.

Updated
8 min read
The Day a “Small” Data Type Choice Slowed Down Everything
R

I am a full-stack developer (currently working with cognizant) who is passionate about web development and creating digital products with innovative solutions.

I hold 6+ years of experience in development, understanding clients' unique needs, and delivering quality code. I've honed my coding skills over these years through both my professional exposure and self-study. Have worked with teams that have used agile development methodology.

I am someone who likes to keep acquiring new skills and capabilities. And when I am not a web developer, I enjoy reading, writing and running.

My interests include:

  • Exploring new ideas
  • Learning about future tech & products
  • Finding user-friendly solutions to tech-related problems
  • Sharing my knowledge with close acquaintances

We didn’t change the business logic.

We didn’t deploy a new feature.

We didn’t add traffic.

But suddenly:

  • Queries were slower.

  • Backups were heavier.

  • Replication lag increased.

  • Financial totals were “slightly off.”

Nothing obvious was broken.

But something felt wrong.

After hours of profiling and EXPLAIN plans, we found it.

Not a bug.

Not a missing index.

A schema mistake.

We had chosen the wrong data types months ago.

And now the database was charging us interest.

That was the day I stopped thinking of MySQL data types as “basic SQL.”

Because data types are not syntax.

They are architecture.

In this guide, we are going to explore 4 key concepts to help you master MySQL data types in real production systems:

  1. Numeric types — INT, TINYINT, BIGINT

  2. DECIMAL vs FLOAT vs DOUBLE

  3. CHAR vs VARCHAR

  4. DATE, DATETIME, and TIMESTAMP

This isn’t about memorizing ranges.

This is about avoiding performance debt and financial bugs.


1️⃣ Data Types: The Containers That Define Your System

Data types define how MySQL stores data internally.

But internally is where scale lives.

They determine:

  • Storage size

  • Index size

  • Memory usage

  • Accuracy

  • Query performance

The Container Analogy (Expanded)

Imagine your database as a warehouse.

Each column is a storage shelf.

Data types are the box sizes.

If you store tiny items in giant boxes:

  • You waste space.

  • You reduce efficiency.

  • You slow down movement.

If you store large items in tiny boxes:

  • They overflow.

  • They break.

  • They get rejected.

Choosing the right type is choosing the right container.

And warehouses don’t forgive bad logistics.


🔢 Numeric Types — INT, TINYINT, BIGINT

What They Are

Whole number types with different ranges and storage sizes:

Type Range (Signed) Storage
TINYINT -128 to 127 1 byte
INT ~2 billion 4 bytes
BIGINT Very large 8 bytes

Looks harmless.

It’s not.


Production Scenario: Inventory System

You’re building an inventory platform.

You need:

  • Product ID

  • Stock quantity

  • is_active flag

CREATE TABLE inventory (
  id INT AUTO_INCREMENT PRIMARY KEY,
  product_name VARCHAR(100),
  quantity INT,
  is_active TINYINT
);

Clean.

Efficient.

Correct.


What Happens If You Use BIGINT Everywhere?

I’ve seen this mindset:

“Storage is cheap. Let’s future-proof.”

Here’s what actually happens at scale:

  • BIGINT doubles storage compared to INT.

  • Indexes double in size.

  • Cache efficiency drops.

  • Joins become heavier.

  • Backup size increases.

  • Replication takes longer.

Multiply 4 extra bytes × 50 million rows.

That’s 200MB — just for one column.

Now multiply that across multiple indexes.

Suddenly “just in case” becomes infrastructure cost.


Senior Dev Perspective

Use BIGINT when:

  • You expect extremely high row counts.

  • You use distributed ID generators.

  • You design global-scale systems.

Otherwise?

INT is enough for most applications.

Smaller types → smaller indexes → faster joins.

That’s not theory.

That’s physics.


💰 DECIMAL vs FLOAT vs DOUBLE — The Finance Trap

This is where junior mistakes become executive-level problems.


DECIMAL — Exact Precision

price DECIMAL(8,2)
  • 8 total digits

  • 2 digits after decimal

Stored exactly.

Perfect for:

  • Prices

  • Banking balances

  • Invoices

  • Accounting


FLOAT and DOUBLE — Approximate Precision

Type Approximate Precision
FLOAT ~7 digits
DOUBLE ~15 digits

Stored in binary floating-point format.

Which means:

0.1 + 0.2 may not equal exactly 0.3.


Debugging Scenario: The Rounding Ghost

Imagine:

You calculate monthly totals using FLOAT.

Individually, everything looks fine.

But when aggregated:

Total revenue = 9999.99999997

Now finance flags discrepancies.

Auditors ask questions.

Customers notice invoice mismatches.

All because of binary approximation.


Senior Dev Perspective

Rule:

  • Money → DECIMAL

  • Analytics → DOUBLE

  • Never FLOAT for finance

Rounding errors in financial systems are not “bugs.”

They’re liability.


🔤 CHAR vs VARCHAR — The Silent Storage Leak

This looks small.

But small schema decisions compound.


VARCHAR — Flexible Storage

name VARCHAR(100)
  • Stores only actual length.

  • Ideal for user input.

  • Efficient.

If name is 5 characters, it stores 5 characters.


CHAR — Fixed Length

country_code CHAR(2)
  • Always uses full length.

  • Predictable storage.

  • Faster for fixed-size values.

Perfect for:

  • Country codes

  • State abbreviations

  • ISO codes

  • Fixed-length hashes


What Happens If You Use CHAR Wrong?

Let’s say:

You store usernames as CHAR(100).

Every row uses 100 characters — even if the name is 6 letters.

Multiply that across millions of users.

Your disk grows.

Backups grow.

Replication slows.

I/O increases.

All because of one column.


Senior Dev Perspective

Use CHAR when:

  • Length is guaranteed fixed.

  • You want predictable storage.

Use VARCHAR otherwise.

Don’t guess.


📅 DATE vs DATETIME vs TIMESTAMP — Where Time Gets Dangerous

Time is easy.

Timezones are not.


Example Table

CREATE TABLE people (
  name VARCHAR(100),
  birthdate DATE,
  birthtime TIME,
  birthdt DATETIME
);

What They Store

Type Stores
DATE Date only
TIME Time only
DATETIME Full date & time
TIMESTAMP Date & time (smaller range)

The difference isn’t cosmetic.

It’s operational.


DATETIME vs TIMESTAMP — The Critical Differences

Feature DATETIME TIMESTAMP
Storage 8 bytes 4 bytes
Timezone No auto conversion Timezone-aware
Use case Historical records Metadata

TIMESTAMP auto-adjusts based on timezone.

DATETIME does not.


Debugging Scenario: The Timezone Nightmare

You deploy globally.

App servers run in different regions.

You store audit logs as DATETIME.

Suddenly:

  • Logs appear out of order.

  • Reports shift by hours.

  • Analytics dashboards look wrong.

Support says, “User created account at 10:00 PM.”

Logs say 4:30 AM.

You lose trust in your own system.


Correct Usage

Use TIMESTAMP for:

  • created_at

  • updated_at

  • log metadata

CREATE TABLE captions (
  text VARCHAR(150),
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE captions2 (
  text VARCHAR(150),
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

Always standardize to UTC.

Timezones are optional for users.

They are not optional for engineers.


📆 Date & Time Functions — Power for Reporting

SELECT DAY(birthdate), MONTHNAME(birthdate), YEAR(birthdate) FROM people;
SELECT DATE_FORMAT(birthdate, '%a %b %D') FROM people;

Used for:

  • Monthly reports

  • Time-based analytics

  • Business dashboards

Correct data types make this efficient.

Wrong ones make this painful.


❌ Common Pitfalls (We’ve All Done One)

  • Using FLOAT for money

  • Using BIGINT everywhere

  • Using CHAR for user input

  • Ignoring timezone handling

  • Storing dates as VARCHAR

Storing dates as VARCHAR deserves a special mention.

That’s not technical debt.

That’s schema sabotage.


🛠 DevOps & SRE View

Data types affect:

  • Backup size

  • Replication speed

  • Query performance

  • Disk I/O

  • Index efficiency

Schema mistakes multiply at scale.

Fixing them later requires:

  • Migrations

  • Downtime

  • Risk

Choosing correctly early costs nothing.

Choosing incorrectly costs everything later.


🧠 The Mental Model That Changes Everything

Data types are not academic.

They are:

  • Performance decisions

  • Cost decisions

  • Reliability decisions

  • Legal decisions

Choosing correctly separates:

Developers who write features
from
Engineers who design systems

The Bridge Back

Remember the slow queries?

We didn’t rewrite business logic.

We didn’t optimize algorithms.

We changed:

  • BIGINT → INT where appropriate

  • FLOAT → DECIMAL for pricing

  • DATETIME → TIMESTAMP for metadata

  • CHAR → VARCHAR for user input

Storage dropped.

Query speed improved.

Finance stopped complaining.

Sometimes the biggest performance wins are hidden in the schema.

And the database never forgets your early shortcuts.


More from this blog

Rajkumar Thangavel

19 posts

Tech enthusiast with nearly a decade of experience as a software developer across banking, telecom, healthcare and e-commerce. I share real-world learning, perspectives, and practical insights.