A Calculator Hiding in Your YugabyteDB Session

I was onsite with a customer when a question came up about core counts, operations per second, and a workload we were discussing.

Instead of opening the calculator app on my phone or MacBook, I opened a YugabyteDB ysqlsh session and typed a SELECT statement.

I did not think anything of it. They thought it was cool.

Apparently, my calculator has a database connection.

YugabyteDB’s YSQL API inherits PostgreSQL’s arithmetic operators and mathematical functions, so you can use it for quick calculations without creating a table or writing a FROM clause.

No table required: Open ysqlsh, type SELECT, add your calculation, and finish with a semicolon. The examples below do not create or modify any tables.

Start with the Basics

Sometimes the entire question is this:

				
					SELECT 2 * 10;
				
			

Result:

				
					 ?column?
----------
       20
(1 row)
				
			

Or this:

				
					SELECT 1000 / 20;
				
			

Result:

				
					 ?column?
----------
       50
(1 row)
				
			

Give the result a name if you want something more useful than ?column?:

				
					SELECT
  2 * 10 AS multiplication,
  1000 / 2 AS division,
  (10 + 5) * 4 AS with_parentheses;
				
			

Expected results: 20, 500, and 60.

One statement. Three answers. The calculator app (on my phone) is starting to look nervous.

The Gotcha: Where Did My Decimal Places Go?

This one deserves attention:

				
					SELECT 1000 / 22;
				
			

Result:

				
					 ?column?
----------
       45
(1 row)
				
			

Both operands are integers, so YSQL performs integer division and truncates the fractional part toward zero.

Make at least one operand a decimal:

				
					SELECT 1000 / 22.0;
				
			

Result:

				
					      ?column?
---------------------
 45.4545454545454545
(1 row)
				
			

Or cast an operand to numeric:

				
					SELECT round(1000::numeric / 22, 2) AS answer;
				
			

Expected answer: 45.45.

Cast before you divide: 1000::numeric / 22 preserves the fraction. (1000 / 22)::numeric converts an already-truncated result. Once integer division has discarded the fraction, a cast cannot bring it back.

And when rounding for capacity, use ceil() if you need to round up:

				
					SELECT
  round(45.45) AS nearest_integer,
  ceil(45.45) AS round_up,
  floor(45.45) AS round_down;
				
			

Expected results: 45, 46, and 45.

You probably cannot provision 0.45 of a server. Your cloud provider may disagree about how to bill it, though.

Back to the Customer Question: How Many Cores?

Here is an illustrative calculation using:

  • ● A target of 50,000 operations per second.
  • ● An assumed 300 operations per second per core.
  • ● 25% added capacity above the target.
  • ● 32 cores per node.

Keep the inputs together so they are easy to change:

				
					WITH inputs AS (
  SELECT
    50000::numeric AS target_ops_per_sec,
    300::numeric AS ops_per_sec_per_core,
    25::numeric AS extra_capacity_pct,
    32 AS cores_per_node
),
sizing AS (
  SELECT
    *,
    target_ops_per_sec * (1 + extra_capacity_pct / 100)
      / ops_per_sec_per_core AS raw_core_estimate
  FROM inputs
)
SELECT
  round(raw_core_estimate, 2) AS calculated_cores,
  ceil(raw_core_estimate)::integer AS minimum_whole_cores,
  ceil(raw_core_estimate / cores_per_node)::integer AS nodes,
  ceil(raw_core_estimate / cores_per_node)::integer
    * cores_per_node AS provisioned_cores
FROM sizing;
				
			

Expected result:

				
					 calculated_cores | minimum_whole_cores | nodes | provisioned_cores
------------------+---------------------+-------+-------------------
           208.33 |                 209 |     7 |               224
(1 row)
				
			

Now the assumptions and the arithmetic are in the same place. Change an input and rerun the statement.

The math is an estimate: The 300 ops/sec/core input is an example, not a YugabyteDB benchmark or sizing guarantee. Use measurements from a representative workload and topology, with a consistent definition of cores and operations. Validate the result against availability, failure capacity, memory, storage, and latency requirements. Also, adding 25% capacity is different from targeting 75% utilization: those use multipliers of 1.25 and 1 / 0.75, respectively.

Ask “What If?” Without Retyping Everything

A regular calculator gives you one answer at a time. SQL can compare several assumptions at once:

				
					WITH assumptions(ops_per_sec_per_core) AS (
  VALUES (250::numeric), (300::numeric), (500::numeric)
)
SELECT
  ops_per_sec_per_core,
  ceil(50000 * 1.25 / ops_per_sec_per_core)::integer
    AS required_cores,
  ceil(50000 * 1.25 / ops_per_sec_per_core / 32)::integer
    AS nodes_with_32_cores
FROM assumptions
ORDER BY ops_per_sec_per_core;
				
			

Expected result:

				
					.ops_per_sec_per_core | required_cores | nodes_with_32_cores
----------------------+----------------+---------------------
                  250 |            250 |                   8
                  300 |            209 |                   7
                  500 |            125 |                   4
(3 rows)
				
			

This is where the SQL calculator starts earning its keep: one formula, multiple scenarios, and the assumptions right beside the results.

How Long Will That Backlog Take?

Suppose you have 250 million rows to process at a sustained 25,000 rows per second:

				
					SELECT
  round(250000000::numeric / 25000, 2) AS seconds,
  round(250000000::numeric / 25000 / 60, 2) AS minutes,
  interval '1 second' * (250000000::numeric / 25000)
    AS elapsed_time;
				
			

Expected values:

				
					seconds:      10000.00
minutes:        166.67
elapsed_time: 02:46:40
				
			

That assumes a steady processing rate and no new arrivals. If rows keep arriving, use the net drain rate: processing rate minus arrival rate.

Going the other direction, what average rate handles 100 million operations per day?

				
					SELECT round(
  100000000::numeric / (24 * 60 * 60),
  2
) AS average_ops_per_second;
				
			

Expected answer: 1157.41.

That is the daily average. Peak traffic gets its own calculation.

Did That Query Get 4x Faster or 75% Faster?

A query goes from 80 ms to 20 ms. Calculate both the latency reduction and the speedup:

				
					WITH measurements AS (
  SELECT 80::numeric AS before_ms, 20::numeric AS after_ms
)
SELECT
  round(100 * (before_ms - after_ms) / before_ms, 2)
    AS latency_reduction_pct,
  round(before_ms / after_ms, 2) AS speedup_factor
FROM measurements;
				
			

Expected results:

				
					latency_reduction_pct: 75.00
speedup_factor:        4.00
				
			

You can accurately say “75% lower latency” or “4x as fast” for that measurement. Much clearer than debating what “75% faster” means.

Big Numbers Need a Bigger Data Type

At 100,000 operations per second, how many operations is that per day?

This looks harmless:

				
					SELECT 100000 * 86400;
				
			

But both operands are ordinary integers, and the result exceeds their range:

				
					ERROR:  integer out of range
				
			

Promote an operand before multiplication:

				
					SELECT 100000::bigint * 86400 AS operations_per_day;
				
			

Expected answer: 8,640,000,000.

Casting the result afterward is too late:

				
					-- Still overflows during multiplication:
SELECT (100000 * 86400)::bigint;
				
			

For large decimal calculations, use numeric. For whole-number counts within its range, bigint is handy.

A Few More Buttons on Your SQL Calculator

				
					SELECT
  abs(-42) AS absolute_value,
  power(2::numeric, 10) AS two_to_the_tenth,
  sqrt(144::numeric) AS square_root,
  mod(1000, 22) AS remainder;
				
			

Expected values: 42, 1024, 12, and 10. Some numeric results may display trailing decimal places.

Dates work, too:

				
					SELECT
  date '2026-11-01' + 30 AS thirty_days_later,
  date '2026-12-31' - date '2026-11-01' AS days_between;
				
			

Expected values: 2026-12-01 and 60.

Or make a large answer easier to read:

				
					SELECT to_char(
  100000::bigint * 86400,
  'FM999,999,999,999,990'
) AS operations_per_day;
				
			

Expected answer: 8,640,000,000.

Final Takeaway

Your YSQL session is already a capable calculator. Use it for quick arithmetic, workload estimates, rates, percentages, date calculations, and side-by-side scenarios.

Just keep the data types in mind: use decimal arithmetic when you need fractions, promote operands before large calculations, and round capacity estimates in the direction the decision requires.

The next time someone asks, “How many cores would that take?” you might already have the right app open.

				
					SELECT 'Who needs a calculator app?' AS takeaway;
				
			

Have Fun!

Just moved to Dallas, and a few work colleagues told me I needed to check out Nebraska Furniture Mart.

“It’s big,” they said. I didn’t believe them. I was wrong. 😂

My wife and I went the other day. She headed for the dining room tables, and I wandered into electronics.

Two hours later, she was waiting on a couch ready to leave… I was still lookin’

I think I’m going to spend a lot of time here. Possibly money, too.