⚠️ NOTE: PTAXSIM relies on a separate SQLite database to function correctly. You must download and decompress the database before using this package! See Database installation for details.Link to PTAXSIM database (DB version: 2022.0.0; Last updated: 2024-01-19 04:40:35)
PTAXSIM is an R package/database to approximate Cook County property tax bills. It uses real assessment, exemption, TIF, and levy data to generate historic, line-item tax bills (broken out by taxing district) for any property from 2006 to 2022. Given some careful assumptions and data manipulation, it can also provide hypothetical, but factually grounded, answers to questions such as:
- What would my property tax bill be if my assessed value was $50K lower? What if my school district’s levy goes up?
- How do appeals affect tax bills? What if nobody appeals?
- How do exemptions affect tax bills? What if a current exemption amount is increased?
- How do TIF districts affect tax bills? What if a nearby TIF district did not exist?
- Where have tax bills changed the most? Where would they change the most given X policy change?
PTAXSIM can generate hundreds, or even millions, of tax bills in a single function call, which enables complex tax analysis on a municipality or even whole-county level. PTAXSIM is accurate (within $10 of the real bill) for >99% of historic property tax bills. However, it is currently an experimental tool only and is not recommended for critical use. See Notes and Disclaimer for more information.
For detailed documentation on included functions and data, visit the full reference list or the introduction vignette.
For examples of PTAXSIM’s functionality and usage, click one of the questions above or see the vignettes page.
Q: Who is the target audience for PTAXSIM?
PTAXSIM is a currently a developer and researcher-focused tool. Its intended audience is academics and policymakers interested in tax policy analysis or the history of the property tax system. It is not intended to predict or explain individual bills. In the future, we plan to make PTAXSIM more accessible via a web frontend and/or API.
Q: I got my Assessment Notice with a new assessed value. Can I input the new assessed value into PTAXSIM to predict next year’s property tax bill?
No. Assessments sent by the Assessor are not final. A property’s assessed value can change at multiple stages: at the Assessor’s Office due to a reassessment, at the Assessor’s Office due to an appeal, and at the Board of Review due to an appeal. Assessments are not finalized until these stages are complete/certified, and only finalized assessments are used to calculate bills.
Additionally, an increased assessed value does not necessarily result in an increased bill. There are many other factors that contribute to a property’s tax bill – including the assessed value of other properties.
Q: I know my property’s final assessed value. Can I input the final assessed value into PTAXSIM to predict next year’s property tax bill?
No. Even if you know your property’s final assessed value with certainty, precisely predicting a future tax bill in Cook County is difficult because tax rates stem from multiple agencies (and the numbers they produce each year). These agencies include various taxing districts (typically 10 to 14 per property, including school districts, municipal/township/city governments, and Cook County), multiple Cook County property tax offices (Assessor, Board of Review, and Clerk), and the Illinois Department of Revenue (IDOR).
It is true, however, that PTAXSIM is technically capable of predicting bills. To do this, you must have technical competency in the R programming language, and must make explicit predictions for each of the numeric inputs listed in the table below.
Q: I can code in R. What other numbers, besides assessed value, do I need to input into PTAXSIM to generate predictions?
To predict next year’s bill for one property (PIN), you must predict the PIN’s taxable value (EAV), as well as what will happen to the individual levies and tax bases of all taxing districts associated with the PIN. The table below lists each input, along with some complications and options:
Input | What this means | Complications and possible implementation option(s) |
---|---|---|
The PIN’s taxable value | The PIN’s Equalized Assessed Value (EAV), which incorporates the assessed value, exemptions, and IDOR’s equalizer. | Complications: In a tax year, AVs can change at the Assessor’s Office and at the Board of Review. Also, IDOR calculates a new equalizer every year. Option: Predict what you think is an accurate AV, apply what exemptions you qualify for, and use past equalizers issued by IDOR. |
Tax extensions, also called levies, for each taxing agency associated with that PIN’s tax code (typically, 10-14 agencies) | The total extension is the total dollar amount each taxing agency decides to collect from property owners within the boundaries of its district. | Complication: Each agency sets their own tax levy. Option: For each agency associated with that PIN’s tax code, you might use the past year extension, and apply a percentage increase or decrease. |
Tax bases for each taxing agency associated with that PIN’s tax code (typically, 10-14 agencies) | For each agency, the tax base equals the sum of the EAVs of all properties in its district, except for any region of the agency that is in a TIF (where the base is frozen). | Complication: Even after a township has been reassessed, many agencies span across township boundaries. (For example: the taxing district of the City of Chicago is divided up into eight assessment townships, but property tax bills for Chicagoans depend on assessments throughout all eight townships). Option: For each agency associated with that PIN’s tax code, you might use the past year total EAV, and apply a percentage increase or decrease. |
You can install the released version of ptaxsim
directly from GitHub
with one of the following commands:
# Using remotes
remotes::install_github("ccao-data/ptaxsim")
# Using renv
renv::install("ccao-data/ptaxsim")
# Using pak
pak::pak("ccao-data/ptaxsim")
# Append the @ symbol for a specific version
remotes::install_github("ccao-data/ptaxsim@0.6.0")
⚠️ NOTE: Windows users may need to install Rtools in order to build and use this package. Please follow the instructions here to install Rtools for your version of R. Once Rtools is installed, installation can proceed normally using the code above.
PTAXSIM relies on a separate SQLite database to function correctly. This database contains the information about properties, taxing districts, and TIF districts necessary to calculate tax bills. To use this database:
- Download the compressed database file from the CCAO’s public S3 bucket. Link here.
- (Optional) Rename the downloaded database file by removing the
version number, i.e. ptaxsim-2022.0.0.db.bz2 becomes
ptaxsim.db.bz2
. - Decompress the downloaded database file. The file is compressed
using bzip2.
- On Windows, you can easily decompress bzip2 files using 7-Zip.
- On *nix systems, bzip2 is typically installed by default and can
be used via the command line i.e.
bzip2 -d ptaxsim.db.bz2
. If bzip2 is not installed, use the package manager on your system (brew, apt, etc.) to install it first.
- Place the decompressed database file (
ptaxsim.db
) in a convenient location, preferably at the root of your R project. - At the beginning of your project, instantiate a
DBI connection to the database file with
the name
ptaxsim_db_conn
. The PTAXSIM R functions look for this connection object name by default. If you wish to change the name, you can pass the custom named object to theconn
argument of each PTAXSIM function. Below is a sample DBI connection:
library(ptaxsim)
# Create the DB connection with the default name expected by PTAXSIM functions
ptaxsim_db_conn <- DBI::dbConnect(RSQLite::SQLite(), "./ptaxsim.db")
PTAXSIM has a single primary function - tax_bill()
- with two required
arguments:
year_vec
- A numeric vector of tax yearspin_vec
- A character vector of Property Index Numbers (PINs)
The output is a data.table
containing the tax amount directed to each
taxing district, by PIN and year. By default, tax_bill()
can only
generate historic tax bills; it cannot generate future or
counterfactual bills. To generate future/counterfactual bills, you must
provide additional data to tax_bill()
via its secondary arguments. See
the introduction
page
for more details.
The simplest use of tax_bill()
is to calculate a single bill for a
single year:
single_bill <- tax_bill(year_vec = 2020, pin_vec = "17341020511001")
single_bill
#> year pin class tax_code av eav agency_num
#> 1: 2020 17341020511001 299 76037 11568 37288 010010000
#> 2: 2020 17341020511001 299 76037 11568 37288 010020000
#> 3: 2020 17341020511001 299 76037 11568 37288 030210000
#> 4: 2020 17341020511001 299 76037 11568 37288 030210001
#> 5: 2020 17341020511001 299 76037 11568 37288 030210002
#> 6: 2020 17341020511001 299 76037 11568 37288 030210529
#> 7: 2020 17341020511001 299 76037 11568 37288 043030000
#> 8: 2020 17341020511001 299 76037 11568 37288 044060000
#> 9: 2020 17341020511001 299 76037 11568 37288 050200000
#> 10: 2020 17341020511001 299 76037 11568 37288 050200001
#> 11: 2020 17341020511001 299 76037 11568 37288 080180000
#> agency_name agency_major_type agency_minor_type
#> 1: COUNTY OF COOK COOK COUNTY COOK
#> 2: FOREST PRESERVE DISTRICT ... COOK COUNTY COOK
#> 3: CITY OF CHICAGO MUNICIPALITY/TOWNSHIP MUNI
#> 4: CITY OF CHICAGO LIBRARY F... MUNICIPALITY/TOWNSHIP LIBRARY
#> 5: CITY OF CHICAGO SCHOOL BL... MUNICIPALITY/TOWNSHIP MISC
#> 6: TIF - CHICAGO - BRONZEVIL... MUNICIPALITY/TOWNSHIP TIF
#> 7: CHICAGO COMMUNITY COLLEGE... SCHOOL COMM COLL
#> 8: BOARD OF EDUCATION SCHOOL UNIFIED
#> 9: CHICAGO PARK DISTRICT MISCELLANEOUS PARK
#> 10: CHICAGO PARK DISTRICT AQU... MISCELLANEOUS BOND
#> 11: METRO WATER RECLAMATION D... MISCELLANEOUS WATER
#> agency_tax_rate final_tax
#> 1: 0.00453 57.57
#> 2: 0.00058 7.37
#> 3: 0.01580 200.79
#> 4: 0.00140 17.79
#> 5: 0.00166 21.10
#> 6: 0.00000 1698.69
#> 7: 0.00151 19.19
#> 8: 0.03656 464.62
#> 9: 0.00329 41.81
#> 10: 0.00000 0.00
#> 11: 0.00378 48.04
To compare this output to a real tax bill, we can reorder the rows and keep only the columns that appear on an actual printed bill.
library(dplyr)
single_bill %>%
select(agency_name, final_tax, agency_tax_rate) %>%
mutate(agency_tax_rate = agency_tax_rate * 100) %>%
arrange(-row_number()) %>%
setNames(c("Agency", "2020 Tax", "2020 Rate")) %>%
knitr::kable("html", digits = 3)
Agency | 2020 Tax | 2020 Rate |
---|---|---|
METRO WATER RECLAMATION DISTRICT OF GREATER CHICAGO | 48.04 | 0.378 |
CHICAGO PARK DISTRICT AQUARIUM & MUSEUM BONDS | 0.00 | 0.000 |
CHICAGO PARK DISTRICT | 41.81 | 0.329 |
BOARD OF EDUCATION | 464.62 | 3.656 |
CHICAGO COMMUNITY COLLEGE DISTRICT 508 | 19.19 | 0.151 |
TIF - CHICAGO - BRONZEVILLE | 1698.69 | 0.000 |
CITY OF CHICAGO SCHOOL BLDG & IMP FUND | 21.10 | 0.166 |
CITY OF CHICAGO LIBRARY FUND | 17.79 | 0.140 |
CITY OF CHICAGO | 200.79 | 1.580 |
FOREST PRESERVE DISTRICT OF COOK COUNTY | 7.37 | 0.058 |
COUNTY OF COOK | 57.57 | 0.453 |
Here’s the real 2020 tax bill for this PIN for comparison:
There are some minor differences between PTAXSIM and the real bill. The taxing district names may not be identical. Additionally, PTAXSIM aggregates the different Cook County agencies (Public Safety, Health Facilities, and County of Cook) into a single line-item (COUNTY OF COOK).
We can also look at a single property over multiple years, in this case
broken out by taxing district. To do so, pass a vector of multiple years
to the year_vec
argument of tax_bill()
:
multiple_years <- tax_bill(2010:2021, "14081020210000")
multiple_years
#> year pin class tax_code av eav agency_num
#> 1: 2010 14081020210000 206 73001 69062 227905 010010000
#> 2: 2010 14081020210000 206 73001 69062 227905 010020000
#> 3: 2010 14081020210000 206 73001 69062 227905 030210000
#> 4: 2010 14081020210000 206 73001 69062 227905 030210001
#> 5: 2010 14081020210000 206 73001 69062 227905 030210002
#> ---
#> 122: 2021 14081020210000 206 73105 70000 210189 043030000
#> 123: 2021 14081020210000 206 73105 70000 210189 044060000
#> 124: 2021 14081020210000 206 73105 70000 210189 050200000
#> 125: 2021 14081020210000 206 73105 70000 210189 050200001
#> 126: 2021 14081020210000 206 73105 70000 210189 080180000
#> agency_name agency_major_type agency_minor_type
#> 1: COUNTY OF COOK COOK COUNTY COOK
#> 2: FOREST PRESERVE DISTRICT ... COOK COUNTY COOK
#> 3: CITY OF CHICAGO MUNICIPALITY/TOWNSHIP MUNI
#> 4: CITY OF CHICAGO LIBRARY F... MUNICIPALITY/TOWNSHIP LIBRARY
#> 5: CITY OF CHICAGO SCHOOL BL... MUNICIPALITY/TOWNSHIP MISC
#> ---
#> 122: CHICAGO COMMUNITY COLLEGE... SCHOOL COMM COLL
#> 123: BOARD OF EDUCATION SCHOOL UNIFIED
#> 124: CHICAGO PARK DISTRICT MISCELLANEOUS PARK
#> 125: CHICAGO PARK DISTRICT AQU... MISCELLANEOUS BOND
#> 126: METRO WATER RECLAMATION D... MISCELLANEOUS WATER
#> agency_tax_rate final_tax
#> 1: 0.00423 964.04
#> 2: 0.00051 116.23
#> 3: 0.00914 2083.05
#> 4: 0.00102 232.46
#> 5: 0.00116 264.37
#> ---
#> 122: 0.00145 225.36
#> 123: 0.03517 4984.70
#> 124: 0.00311 483.37
#> 125: 0.00000 0.00
#> 126: 0.00382 593.71
The tax_bill()
function will automatically combine the years and PIN
into their Cartesian product. The result is a tax amount per taxing
district, per PIN, per year. We can collapse these amounts and then plot
them to see how a single PIN has changed over time:
multiple_years_summ <- multiple_years %>%
group_by(year, agency_minor_type) %>%
summarize(final_tax = sum(final_tax)) %>%
mutate(
agency_minor_type = factor(
agency_minor_type,
levels = c(
"TIF", "BOND", "COOK", "LIBRARY", "MUNI", "PARK",
"UNIFIED", "COMM COLL", "WATER", "MISC"
)
)
)
Click here to show plot code
library(ggplot2)
# Plot the amount of taxes going to each district over time
multiple_years_plot <- ggplot(data = multiple_years_summ) +
geom_area(aes(x = year, y = final_tax, fill = agency_minor_type)) +
geom_vline(xintercept = 2016, linetype = "dashed", alpha = 0.3) +
annotate(
"text",
x = 2015.8,
y = 12500,
label = "RPM TIF enacted",
hjust = 1
) +
scale_y_continuous(
name = "Total Tax Amount",
labels = scales::dollar,
expand = c(0, 0)
) +
scale_x_continuous(name = "Year", n.breaks = 7) +
scale_fill_manual(values = scales::hue_pal()(10)) +
theme_minimal() +
guides(fill = guide_legend(title = "District Type"))
For more advanced usage, such as counterfactual analysis, see the vignettes page.
The PTAXSIM backend database contains cleaned data from the Cook County Clerk, Treasurer, and Assessor. The database is updated whenever all the data necessary to calculate a new tax year becomes available. Typically this occurs roughly a year after assessments are mailed i.e. 2019 bill data was available in mid-2020.
Table Name | Source Agency | Source Link | Ingest Script | Contains |
---|---|---|---|---|
agency | Clerk | Tax Extension - Agency Tax Rate Reports | data-raw/agency/agency.R | Taxing district extensions, limits, and base EAV |
agency_info | Clerk + imputed | Tax Extension - Agency Tax Rate Reports | data-raw/agency/agency.R | Taxing district name, type, and subtype |
agency_fund | Clerk | Tax Extension - Agency Tax Rate Reports | data-raw/agency/agency.R | Funds and line-items that contribute to each district’s extension |
agency_fund_info | Clerk | Tax Extension - Agency Tax Rate Reports | data-raw/agency/agency.R | Fund name and whether the fund is statutorily capped |
cpi | IDOR | History of CPI’s Used for the PTELL | data-raw/cpi/cpi.R | CPI-U used to calculate PTELL limits |
eq_factor | Clerk | Tax Extension - Agency Tax Rate Reports | data-raw/eq_factor/eq_factor.R | Equalization factor applied to AV to get EAV |
pin | Clerk + Treasurer | CLERKVALUES and TAXBILLAMOUNTS internal SQL tables | data-raw/pin/pin.R | PIN-level tax code, AV, and exemptions |
tax_code | Clerk | Tax Extension - Tax Code Agency Rate Reports | data-raw/tax_code/tax_code.R | Crosswalk of tax codes by district |
tif | Clerk | TIF Reports - Cook County Summary Reports | data-raw/tif/tif.R | TIF revenue, start year, and cancellation year |
tif_crosswalk | Clerk | Manually created from TIF summary and distribution reports | data-raw/tif/tif.R | Fix for data issue identified in #39 |
tif_distribution | Clerk | TIF Reports - Tax Increment Agency Distribution Reports | data-raw/tif/tif.R | TIF EAV, frozen EAV, and distribution percentage by tax code |
Click here to show full database diagram
erDiagram
agency {
int year PK
varchar agency_num PK
boolean home_rule_ind
int agg_ext_base_year
bigint lim_numerator
bigint lim_denominator
double lim_rate
bigint prior_eav
bigint curr_new_prop
bigint cty_cook_eav
bigint cty_dupage_eav
bigint cty_lake_eav
bigint cty_will_eav
bigint cty_kane_eav
bigint cty_mchenry_eav
bigint cty_dekalb_eav
bigint cty_grundy_eav
bigint cty_kankakee_eav
bigint cty_kendall_eav
bigint cty_lasalle_eav
bigint cty_livingston_eav
bigint cty_total_eav
double pct_burden
bigint total_levy
bigint total_max_levy
double total_prelim_rate
bigint total_reduced_levy
bigint total_final_levy
double total_final_rate
varchar reduction_type
double reduction_pct
double total_non_cap_ext
double total_ext
}
agency_info {
varchar agency_num PK
varchar agency_name
varchar agency_name_short
varchar agency_name_original
varchar major_type
varchar minor_type
}
agency_fund {
int year PK
varchar agency_num PK
varchar fund_num PK
bigint levy
double loss_pct
bigint levy_plus_loss
double rate_ceiling
bigint max_levy
double prelim_rate
bigint ptell_reduced_levy
boolean ptell_reduced_ind
bigint final_levy
double final_rate
}
agency_fund_info {
varchar fund_num PK
varchar fund_name
boolean capped_ind
}
cpi {
int year
double cpi
double ptell_cook
int levy_year PK
}
eq_factor {
int year PK
double eq_factor_tentative
double eq_factor_final
}
metadata {
varchar db_version
varchar requires_pkg_version
varchar created_with_pkg_version
varchar created_at
varchar created_by
varchar author_name
varchar author_email
varchar source_url_database
varchar source_url_package
int data_year_min
int data_year_max
}
pin {
int year PK
varchar pin PK
varchar class
varchar tax_code_num
double tax_bill_total
int av_mailed
int av_certified
int av_board
int av_clerk
int exe_homeowner
int exe_senior
int exe_freeze
int exe_longtime_homeowner
int exe_disabled
int exe_vet_returning
int exe_vet_dis_lt50
int exe_vet_dis_50_69
int exe_vet_dis_ge70
int exe_abate
}
pin_geometry {
int year
varchar pin10
double longitude
double latitude
text geometry
}
pin_geometry_raw {
varchar pin10 PK
int start_year PK
int end_year PK
double longitude
double latitude
text geometry
}
tax_code {
int year PK
varchar agency_num PK
double agency_rate
varchar tax_code_num PK
double tax_code_rate
}
tif {
int year PK
varchar agency_num PK
double prev_year_revenue
double curr_year_revenue
int first_year
boolean cancelled_this_year
}
tif_crosswalk {
int year
varchar agency_num_dist
varchar agency_num_final
}
tif_distribution {
int year PK
varchar agency_num PK
varchar tax_code_num PK
double tax_code_rate
bigint tax_code_eav
bigint tax_code_frozen_eav
bigint tax_code_revenue
double tax_code_distribution_pct
}
eq_factor ||--|{ pin : "applies to"
pin ||--|{ tax_code : "within"
cpi ||--|{ agency : "applies to"
tax_code }|--|| agency : "has"
tax_code ||--o| tif_distribution : "may have"
agency ||--|{ agency_fund : "contains"
agency_info ||--|{ agency : "describes"
agency_fund_info ||--|{ agency_fund : "describes"
tif ||--|| tif_crosswalk : "in"
tif_distribution }|--|| tif_crosswalk : "in"
agency_info ||--o{ tif: "describes"
tax_code }|--o| tif : "may have"
pin_geometry ||--o| pin : "has"
pin_geometry }|--|| pin_geometry_raw : "expands"
erDiagram
agency {
int year PK
varchar agency_num PK
boolean home_rule_ind
bigint cty_cook_eav
double total_ext
}
agency_info {
varchar agency_num PK
varchar agency_name
varchar major_type
}
agency_fund {
int year PK
varchar agency_num PK
varchar fund_num PK
bigint final_levy
double final_rate
}
agency_fund_info {
varchar fund_num PK
varchar fund_name
boolean capped_ind
}
cpi {
int year
double cpi
double ptell_cook
int levy_year PK
}
eq_factor {
int year PK
double eq_factor_tentative
double eq_factor_final
}
metadata {
varchar db_version
varchar requires_pkg_version
int data_year_min
int data_year_max
}
pin {
int year PK
varchar pin PK
varchar class
}
pin_geometry {
int year
varchar pin10
text geometry
}
tax_code {
int year PK
varchar agency_num PK
double agency_rate
varchar tax_code_num PK
double tax_code_rate
}
tif {
int year PK
varchar agency_num PK
double prev_year_revenue
double curr_year_revenue
int first_year
boolean cancelled_this_year
}
tif_crosswalk {
int year
varchar agency_num_dist
varchar agency_num_final
}
tif_distribution {
int year PK
varchar agency_num PK
varchar tax_code_num PK
double tax_code_distribution_pct
}
eq_factor ||--|{ pin : "applies to"
pin ||--|{ tax_code : "within"
cpi ||--|{ agency : "applies to"
tax_code }|--|| agency : "has"
tax_code ||--o| tif_distribution : "may have"
agency ||--|{ agency_fund : "contains"
agency_info ||--|{ agency : "describes"
agency_fund_info ||--|{ agency_fund : "describes"
tif ||--|| tif_crosswalk : "in"
tif_distribution }|--|| tif_crosswalk : "in"
agency_info ||--o{ tif: "describes"
tax_code }|--o| tif : "may have"
pin_geometry ||--o| pin : "has"
- Currently, the per-district tax calculations for properties in the Red-Purple Modernization (RPM) TIF are slightly flawed. However, the total tax bill per PIN is still accurate. See issue #4 for more information.
- Special Service Area (SSA) rates must be calculated manually when creating counterfactual bills. See issue #3 for more information.
- In rare instances, a TIF can have multiple
agency_num
identifiers (usually there’s only one per TIF). Thetif_crosswalk
table determines what the “main”agency_num
is for each TIF and pulls the name and TIF information using that identifier. See issue GitLab #39 for more information. - PTAXSIM is relatively memory-efficient and can calculate every district line-item for every tax bill for the last 15 years (roughly 350 million rows). However, the memory required for this calculation is substantial (around 100 GB).
- PTAXSIM’s accuracy is measured automatically with an integration test. The test takes a random sample of 1 million PINs, calculates the total bill for each PIN, and compares it to the real total bill.
- This repository contains an edited version of PTAXSIM’s commit history. Historical Git LFS and other data files (.csv, .xlsx, etc.) were removed in the transition to GitHub. The most current version of these files is available starting in commit 1f06639. If you need the historical LFS files for any reason, please visit the GitLab archive of this repository.
This package and the included database are for educational purposes only. The Assessor’s office releases the package and database without any representations or warranties of any kind, whether express or implied. Any data, figures, or amounts contained within the package/database, used by the package/database, or produced by the package are solely for illustrative purposes.
Any results produced by this package as distributed are not official, as they are hypothetical, and should not be relied upon for any business or commercial purpose. The Assessor’s office expressly disclaims any liability for any entity’s reliance on this package and/or database.
The PTAXSIM package consists of two components, a package and a
database, each of which can be updated independently. Both components
have built-in checks to ensure that minimum version expectations are
met, i.e. package version 0.5.4
expects database version 2021.0.1
or
higher, and database version 2021.0.1
expects package version 0.5.3
or higher.
The package uses the SemVer schema for
versioning: <MAJOR VERSION>.<MINOR VERSION>.<PATCH>
.
The database uses a custom schema for versioning:
<TAX YEAR>.<MAJOR VERSION>.<MINOR VERSION>
. Where TAX YEAR
denotes
the most recent year of data in the database.
The PTAXSIM database is updated whenever all the data necessary to calculate a new tax year becomes available. Typically this occurs about a year after initial assessments are mailed. Once all necessary data is available, it is manually incorporated into the database, and the database tax year version is updated to reflect the new data.
The process of updating the package and/or database can be somewhat involved. As such, please use the following release checklists when creating a new version: