Seeking to understand the formula details that PoolMath uses to calculate CSI for a salt water pool.


New member
Sep 1, 2018
Wellington, FL

My pool:
21000 gallon in-ground gunite salt water pool, new October 2018, screened in.
Hayward PL-PS4 controller, Hayward T-CELL-9 salt cell, Hayward C3030 cartridge filter, Hayward Ecostar SP3400VSP pump.
Set to do a little over 2 full turnovers per day.
South Florida climate.
Brushed and vacuumed regularly.
Taylor K-2006 FAS-DPD titration test kit, fresh chemicals.

My recent Taylor readings:
pH: 7.6
total alkalinity: 90ppm
calcium hardness: 250ppm
stabilizer: 70ppm
water temp: 85F
salt: 3300ppm


I use a spreadsheet to log all my pool test values, and it auto-calculates CSI values.
Here's an example layout for the spreadsheet:

cell# value
A1 pH
B1 total alkalinity ppm
C1 calcium hardness ppm
D1 water temp F
E1 cyanuric acid ppm
F1 salt ppm

To determine the carbonate alkalinity, I use a vlookup function to derive the cyanurate factor from pH and cyanuric acid ppm, then multiply that factor by the cyanuric acid ppm. That gives me the cyanurate alkalinity ppm. Then I subtract that cyanurate alkalinity from the total alkalinity, to get the true carbonate alkalinity, which is used in the CSI formula.

Here's the lookup table I'm using in the spreadsheet (from TAYLOR "POOL & SPA WATER CHEMISTRY") for the vlookup to determine the cyanurate factor (this table is in spreadsheet cells P1:Q10):

6.5 0.11
7 0.22
7.2 0.26
7.4 0.3
7.6 0.33
7.8 0.35
8 0.36
8.5 0.38

Here's the spreadsheet formula I use to auto-calculate CSI:
=A1 + (0.4341*LN((B1-(D1*(VLOOKUP(A1,$P$1:$Q$10,2)))))+0.0074) + (0.4943*LN(C1)-0.7661) + ((0.0105*E1)-0.2368) - 12.34

It looks complicated with the logarithmic functions, but it's just 5 parts:
the Ph factor
the carbonate alkalinity factor
the calcium hardness factor
the cyanuric acid factor
the correction factor for salt pools (~3400ppm salt should be about -12.34)
This calculates a CSI of -.29

When I enter my 6 measurements into the PoolMath, it gives me -.24

Close enough, but I am curious to know the formulaic details that PoolMath uses, and if I need to adjust any of the values I'm using in my spreadsheet.
I would have attached a sample spreadsheet to clarify the above info, but the .xlsx file format is not allowed for upload.


TFP Expert
LifeTime Supporter
May 3, 2007
Pleasanton, CA
Pool Size
Salt Water Generator
It uses the same formulas that are in this spreadsheet:

Unhide rows 36-42


New member
Sep 1, 2018
Wellington, FL
Thank you very much for that, very interesting!

When I enter my numbers into PoolMath, it gives a CSI of -.24.
Curiously though, entering the same numbers into your referenced source spreadsheet, gives a CSI of -.23.
Not an appreciable difference, but PoolMath is apparently using a slightly different algorithm.
Probably not worth worrying about.

btw, your spreadsheet also seems to agree with this other online calculator: Pool Dosing and LSI Calculator by Orenda

but it is different from the calculator here:
(which was the basis for my initial formulas)

In any event, I'm inclined to change my spreadsheet formulas to utilize the source you referenced.



TFP Expert
LifeTime Supporter
May 3, 2007
Pleasanton, CA
Pool Size
Salt Water Generator
All the equations are the same ones that are used in pool math I think it is due to this formula:

Math.floor(CSI * 100 + 0.5) / 100

They always round down toward zero. I don't round.

[EDIT] Also, I think that the log functions of the two platforms may be giving slightly different answers since the fully calculated value is actually -0.233334

Here is the Pool Math formula:

function CSI(PH, TA, CH, CYA, Salt, Borate, Temp) {
var Sodium, extra_NaCl, CarbAlk, Ionic, TDS, CSI;

if (PH < 6 || PH > 9 || isNaN(PH)) return ("PH Err");
TA = parseInt(TA);
CH = parseInt(CH);
CYA = parseInt(CYA)
Salt = parseInt(Salt);
Borate = parseInt(Borate);
if (document.F.Units.selectedIndex != 1) Temp = (parseInt(Temp) - 32) * 5 / 9;
else Temp = parseInt(Temp);
// if (Salt<=0) Salt = CH*1.1678 + TA*1.6859 + Borate*2.6976;
// Sodium = 23*( (TA - CYA/3)*2/100 + CYA/129 + Salt/58.4 - 2*CH/100 );
// TDS = CH*(40/100) + (TA - CYA/3)*2*(61/100) + CYA*(128/129) +
// Borate*(61.8/10.8) + Salt*(35.5/58.4) + Sodium;
CarbAlk = TA - 0.38772 * CYA / (1 + Math.pow(10, 6.83 - PH)) -
4.63 * Borate / (1 + Math.pow(10, 9.11 - PH));
// extra_NaCl = TDS - (1.109*CH + 1.679*CarbAlk + CYA);
extra_NaCl = Salt - 1.1678 * CH;
if (extra_NaCl < 0) extra_NaCl = 0;
Ionic = (1.5 * CH + 1 * TA) / 50045 + extra_NaCl / 58440;
CSI = PH - 11.677 + Math.log(CH) / Math.LN10 + Math.log(CarbAlk) / Math.LN10 -
2.56 * Math.sqrt(Ionic) / (1 + 1.65 * Math.sqrt(Ionic)) -
1412.5 / (Temp + 273.15) + 4.7375;
return (Math.floor(CSI * 100 + 0.5) / 100);

Using the Excel version of the worksheet gives the same answer -0.233334
Last edited:
Thread Status
Hello , This is an inactive thread. Any new postings here are unlikely to be seen or responded to by other members. You will get much more visibility by Starting A New Thread