Data study 02 of 09 · Homelessness services

Did the 2023 refugee crisis change Toronto's shelter numbers?

In the summer of 2023, refugee claimants sleeping outside a downtown intake office made national news. I used the city's own monthly counts to ask what actually changed, when, and for how long.

City of Toronto open data 54 months of counts, two groups ~4 minute read Skip to the technical notes

This page comes in two parts: the story in plain language first, then technical notes with the specification, full estimates, and robustness checks.

The question

The city's own numbers let us test the story

Toronto publishes a monthly count of people actively using its shelter system, split into groups, including refugee claimants. That makes a genuine test possible: was the crisis a sudden shock, or the visible peak of something that had been building for a long time?

My approach is a before-and-after comparison with a comparison group, a standard tool for judging whether an event changed a trend. The idea is simple: follow the refugee numbers for many months before and after the crisis, and follow everyone else in the shelter system over the same months. If something citywide happened, like winter or a change in how people are counted, it should show up in both groups. A change that appears only in the refugee numbers is much more likely to be about refugees specifically.

How to read the first chart: each thin vertical bar is one month's count of refugee claimants in the shelter system, from January 2022 to June 2026. The gray line behind it is the non-refugee shelter population, every shelter user the policy did not apply to, shown for comparison. The shaded band marks June and July 2023, the months the crisis was in the news.

Refugee shelter numbers had been climbing 6% a month for a year and a half before the crisis made news

refugee claimants (one bar per month) · non-refugee shelter users, for comparison · dashed hairline = the model's own fit, drawn over the data (R² = 0.97) · Jan 2022 – Jun 2026

funding standoff · Jun–Jul 2023 0 2,000 4,000 6,000 8,000 climbing 6% a month before the crisis peak 6,198 · May 2024 after the crisis: a lasting +21% above the pre-crisis path (95% range +6 to +38) 2022 2023 2024 2025 2026

City of Toronto Shelter System Flow · people actively experiencing homelessness, monthly counts

The eye already catches the main finding: the refugee count was climbing steadily, about 6% every month, for a year and a half before the crisis made the news. The crisis months themselves show no sudden spike. The numbers kept rising afterward, peaked in spring 2024, and have been easing since.

The result

The lasting change came after the crisis, and it stayed

The model puts numbers on what the eye sees, and adds an honesty check.

How to read the second chart: each bar is the model's best estimate of how far the refugee count moved compared with where its pre-crisis path was heading. The whisker is the range we can be fairly confident in; if it crosses zero, the change could plausibly be nothing. The bottom row is a deliberate trick played on ourselves: it runs the exact same test on people the crisis funding did not target. If that row showed a big change too, it would mean the method was picking up city-wide noise rather than a refugee-specific effect.

The lasting change came after the crisis: counts settled 21% above the old path

How far refugee counts moved compared with where the pre-crisis path was heading – whiskers mark 95% confidence ranges – the bottom row repeats the test on people the crisis funding did not target

−10% 0 +10% +20% +30% +40% During the episode Jun–Jul 2023, refugee claimants +3.3% p = .593 Sustained level after Aug 2023 onward, refugee claimants +21.0% p = .004 Placebo check same two months, non-refugees −3.6% p = .25

City of Toronto Shelter System Flow · the model tracks 97% of the month-to-month movement

The crisis months show a small, uncertain wobble. The change that holds up is the lasting one: after the episode, refugee shelter counts sat about 21% above where the earlier trend was heading, and stayed elevated for many months. The check row stays near zero, which is exactly what it should do.

A craft detail: my first version of the model assumed the after-period followed a straight line. The real data rises, rounds a peak, and comes back down, and the straight line visibly missed that shape. The published model uses a curve, which tracks 97% of the month-to-month movement. Checking a model against a picture of the data it claims to describe is a habit, not an afterthought.

The upstream driver

Where the wave came from

Toronto's shelter system sits downstream of a national process: people claim asylum first, and some of them need a shelter bed later. Canada's immigration department publishes how many asylum claims are filed each month, so the two series can be laid side by side.

How to read this chart: the two lines measure very different things, so both are scaled to 100 at January 2022 and the chart compares their shapes. Ontario asylum claims more than quadrupled from early 2022 to their 2024 peak, then fell steeply after federal policy tightened. Toronto's refugee shelter count rode the same wave in a flatter form: a shelter bed holds a person for months, so the stock rises and falls more slowly than the flow of new claims that feeds it. One caution: not every claimant needs a shelter, and the shelter series counts people while the claims series counts filings, so this chart shows a shared wave rather than a one-to-one pipeline.

Behind the shelter curve: Ontario asylum claims rose and fell on the same wave

refugee claimants in Toronto shelters · new asylum claims filed in Ontario each month – both series scaled so January 2022 = 100, so shapes can be compared across very different units

0 Jan 2022 = 100 100 200 300 400 500 claims peak: 5.1× the Jan 2022 level shelter peak: 3.6× refugees in shelter Ontario asylum claims 2022 2023 2024 2025 2026

City of Toronto Shelter System Flow + IRCC asylum claimants open data (values rounded to multiples of 5 at source)

What this does not prove

The honest fine print

The comparison group protects against citywide changes, but it cannot rule out everything. Federal border policy, hotel programs, and city intake rules all moved during these years, and some of them touched refugees specifically. This study describes what changed and when; pinning down exactly which policy caused which bend in the curve would take more than one city's numbers.

Technical terms, translated

Comparison group
People the event should not have affected, tracked over the same months. They show what "normal" looked like, so you can spot what is genuinely unusual.
Placebo check
Running your own test where it should find nothing. If it "finds" something anyway, your method is broken. Ours found nothing, which is a pass.
95% confidence range (the whiskers)
Monthly counts bounce around. The whisker marks the range the true change very likely falls in, given that bounce.
"Tracks 97% of the movement"
A score for how closely the model's curve follows the real monthly numbers. 100% would mean a perfect trace.
"Scaled to 100" (the claims chart)
Shelter counts and claim filings use different units, so both lines are re-expressed as multiples of their own January 2022 value. A value of 400 means four times the starting level.
Toronto Shelter System Flow Before-and-after analysis Python Auto-refreshes monthly (GitHub Actions)
Part two · For technical readers

Technical notes

The specification, full estimates, and the checks behind the plain-language claims above.

Data

City of Toronto Shelter System Flow open data: monthly counts of people actively experiencing homelessness, by population group. Window: January 2022 to June 2026, 54 months each for the refugee and non-refugee series (n = 108 group-months). Counts are administrative and occasionally revised; a scheduled GitHub Actions workflow re-pulls the dataset monthly so the analysis tracks revisions.

Design and estimation

Controlled interrupted time series on log counts, in the segmented-regression framework described by Bernal, Cummins and Gasparrini (2017). Treated series: refugee claimants; comparison: all other shelter clients. The event window is a two-month pulse (June and July 2023) with the post period starting August 2023. Specification: log(count) ~ t + G + G:t + pulse + G:pulse + post + G:post + t_post + G:t_post + t_post² + G:t_post² + seasonal terms, where G marks the refugee series and the seasonal terms are annual and semi-annual sine-cosine pairs. Refugee-specific effects are the G-interactions. Heteroskedasticity and autocorrelation consistent standard errors with 6 lags (Newey and West, 1987) handle serial correlation in the monthly counts. Coefficients are reported as percentage changes, (e^b − 1) × 100.

log Ygt = β0 + β1t + β2Pt + β3At + β4τt + β5τt2 + s(t) + Gg·[α0 + α1t + α2Pt + α3At + α4τt + α5τt2] + εgt

where Gg = 1 for the refugee series, Pt = 1 in June–July 2023 (the pulse), At = 1 from August 2023, τt = months since August 2023 (0 before), and s(t) holds annual and semi-annual sine–cosine pairs. The reported refugee-specific effects are α2 (pulse), α3 (sustained level) and α5 (curvature); Newey–West errors, 6 lags.

Controlled ITS estimates, refugee-specific terms (% change in counts)
TermEstimate95% CIp
Pre-period trend, per month+6.0%+4.8 to +7.2< 0.001
Crisis-months pulse (Jun–Jul 2023)+3.3%−8.2 to +16.20.593
Post-period level shift+21.0%+6.2 to +37.90.004
Post-period linear trend, per month−0.82%−2.78 to +1.170.416
Post-period curvature−0.19%−0.23 to −0.15< 0.001
Control-series pulse (non-refugees)−6.1%−9.4 to −2.6< 0.001

n = 108 group-months. OLS on log counts with annual and semi-annual sine-cosine seasonal terms; Newey-West (HAC) standard errors, 6 lags; R² = 0.97. Effects converted as (e^b − 1) × 100.

Robustness checks
CheckEstimate95% CIp
Refugees-only model: pulse−5.5%−13.5 to +3.30.211
Refugees-only model: post trend, per month−1.6%−2.6 to −0.50.005
Placebo (non-refugees alone): pulse−3.6%−9.3 to +2.60.250
Window extended to Jan 2021: pulse+2.7%−12.5 to +20.40.747
Window extended to Jan 2021: post level+19.7%+0.0 to +43.10.049

The post-period level shift survives the wider window at the boundary of significance; the crisis-months pulse reaches significance in no specification.

Model choice

A linear post-trend was fitted first and rejected on visual inspection against the fitted series: it cut through the 2023–24 hump instead of tracking it, and R² rose from 0.91 to 0.97 with the quadratic. The curvature term is the most precisely estimated effect in the model, which is the statistical way of saying the rise-peak-decline shape is real.

Threats to validity

The comparison series absorbs citywide shocks but leaves refugee-specific confounding open: federal border policy, the hotel program, and intake-rule changes all moved inside the window. Announcement and implementation dates blur, so the two-month pulse window is a judgment call; the extended-window sensitivity shows the level shift does not depend on where the pre-period starts. Log-scale effects are multiplicative, so the +21% shift compounds on a series that had already grown.

The same study in SQL

This study's three sources also live in one relational database (population_groups to shelter_monthly by foreign key, plus asylum_claims and the model's fitted values), built with enforced integrity: composite primary keys and CHECK constraints on every count. Ten queries then take a wider tour of the language than the other two SQL rebuilds on this site: a data-quality audit (a LAG-based calendar-continuity check, and a proof that the refugee and non-refugee series partition the total caseload in all 102 months), the context table pivoted with conditional aggregation, peak detection by window rank, a rolling three-month frame, the cross-source IRCC join indexed to January 2022 with FIRST_VALUE, and this one, a regression computed in nothing but aggregates:

-- OLS slope of ln(actively homeless) on a month index,
-- refugee series, pre-crisis window: beta = cov(x,y) / var(x)
WITH series AS (
    SELECT (CAST(strftime('%Y', m.month) AS INT) * 12
              + CAST(strftime('%m', m.month) AS INT)) AS x,
           LN(m.actively_homeless)                    AS y
    FROM shelter_monthly m
    JOIN population_groups g USING (group_id)
    WHERE g.name = 'Refugees'
      AND m.month BETWEEN '2022-01-01' AND '2023-05-01'
),
stats AS (SELECT AVG(x) AS xbar, AVG(y) AS ybar FROM series)
SELECT (EXP(SUM((x - xbar) * (y - ybar))
            / SUM((x - xbar) * (x - xbar))) - 1) * 100
           AS pct_growth_per_month
FROM series, stats;
-- returns +5.08% a month; the full model with seasonality and
-- Newey-West errors reads +6.0% [4.8, 7.2]

An automated checker verifies every query against the committed outputs and independent recomputes (the slope to the sixth decimal): 38 of 38 match.

Reproducibility

Three scripts (get_data.py, run_analysis.py, make_charts.py) on pandas and statsmodels, plus the refresh workflow. Every number on this page comes from the committed results.json and fitted-series CSV. The SQL rebuild adds build_db.py, queries.sql, and run_checks.py in the project's sql/ folder.

References

  • City of Toronto. (2026). Toronto Shelter System Flow [data set]. City of Toronto Open Data Portal. https://open.toronto.ca/dataset/toronto-shelter-system-flow/ (data through June 2026; retrieved July 2026).
  • Immigration, Refugees and Citizenship Canada. (2026). Asylum claimants: monthly IRCC updates [data set]. Open Government Portal. https://open.canada.ca/data/en/dataset/b6cbcf4d-f763-4924-a2fb-8cc4a06e3de4 (data through May 2026; retrieved July 2026; counts rounded to multiples of 5 at source).
  • Bernal, J. L., Cummins, S., & Gasparrini, A. (2017). Interrupted time series regression for the evaluation of public health interventions: a tutorial. International Journal of Epidemiology, 46(1), 348–355.
  • Newey, W. K., & West, K. D. (1987). A simple, positive semi-definite, heteroskedasticity and autocorrelation consistent covariance matrix. Econometrica, 55(3), 703–708.