How ImmoDash works
Eleven public datasets become one tested picture of the German rental market, rebuilt automatically every week.
From raw files to this page
Each step is automated and tested. If any step fails, nothing is published and the site keeps the last good data.
- 01Python ingestion, raw files kept as-is (bronze)
Collect
Eleven open datasets: Zensus 2022, GREIX listings, Bundesbank loan rates, regional incomes, district and postcode boundaries.
- 02dbt on DuckDB / PostgreSQL, 75 data tests
Clean and test
Tables are joined to Germany's 400 districts and checked automatically: no gaps, no impossible values.
- 03LightGBM quantile regression, conformal intervals, robust z-scores
Model
A forecasting model predicts each city's rent 3, 6 and 12 months ahead, and unusual months are flagged.
- 04FastAPI, 25 endpoints, Pydantic contracts
Serve
Every number on this site comes from one typed interface, so the website and analyst tools never disagree.
- 05Groq LLM + numeric grounding check
Explain
An AI model writes each city summary from a fixed list of facts. If it uses a number that is not in the list, the text is thrown away.
- 06GitHub Actions, Next.js static export on Vercel
Publish
Every Monday the whole chain reruns and this site is rebuilt from the fresh data.
We tested the model on data it had never seen
Over 12 months the model was off by 1.74% on average. Assuming rents stay the same was off by 4.59%, and extending last year's trend by 2.33%. That is about 62% smaller errors than the no-change guess.
82% of real outcomes fell inside the model's 80% range, close to the 80% it promises.
Average forecast error, lower is better
Mean absolute percentage error, out of sample.
Show the numbers
| Horizon | Model | Error | 80% range hit rate |
|---|---|---|---|
| 3 months | ImmoDash model | 1.06% | 81% |
| 3 months | Trend continues | 1.32% | n/a |
| 3 months | No change | 1.51% | n/a |
| 6 months | ImmoDash model | 1.22% | 77% |
| 6 months | Trend continues | 1.58% | n/a |
| 6 months | No change | 2.43% | n/a |
| 12 months | ImmoDash model | 1.74% | 82% |
| 12 months | Trend continues | 2.33% | n/a |
| 12 months | No change | 4.59% | n/a |
What each number means
Asking rent
The middle price per m² of flats advertised for rent in a month. Half of the listings cost more, half cost less.
Median of listing prices, GREIX hedonic index (adjusts for flat size and quality)New-lease premium
How much more someone signing a lease today pays than the average existing tenant paid in 2022.
Asking rent ÷ Zensus 2022 average contract rent − 1Based on [4]
Rent burden
How much of a typical household's income the rent for a 60 m² flat would take.
Rent × 60 m² × 12 ÷ (2 × disposable income per resident)Affordability index
The rent burden compared with the typical German district: 100 is average, higher is more affordable.
Median district burden ÷ district burden × 100Estimated asking rent (districts)
For districts without listing data: the census rent raised by the gap between census and asking rents seen in nearby tracked cities.
Zensus rent × (1 + premium of the city, else state median, else national median)Rent range within a district
Rents differ from street to street. The range shows the cheaper and dearer ends of a district, leaving out the cheapest and dearest 10% of its area.
District estimate × (10th and 90th percentile ÷ median) of Zensus grid cells: 100 m in the 37 cities, 1 km elsewherePostcode estimate
For the 37 cities: how a postcode compares with the rest of its city, applied to the city-wide estimate.
District estimate × median grid rent of the postcode's 100 m cells ÷ city median (postcode areas: OpenStreetMap)Supply-demand index
High when few flats are empty and the population is growing.
z(population growth 2018 to 2023) − z(empty and available flats, 2022); ≥ 1 tight, ≤ −1 slackLive market pressure
How quickly flats are let in practice: days online and the share gone within a week.
Mean z-score of (inverted) days on market and share let within a week, per quarterUnusual month
A month where one city moved far more than the others, compared with its own last two years.
City change minus all-city median change; robust z vs. previous 24 months; |z| ≥ 3.5Based on [16]
References
Lebuhn, H., Holm, A., Junker, S. & Neitzel, K. (2017). Wohnverhältnisse in Deutschland: eine Analyse der sozialen Lage in 77 Großstädten. Humboldt-Universität zu Berlin, funded by the Hans-Böckler-Stiftung (press release, 13 September 2017).
Used for: Rent above 30% of household net income is treated as problematic, and many landlords use the same limit.
Deutsche Bundesbank (2024). Preise für Wohnimmobilien sanken 2023 deutlich; Mieten stärker unter Druck. Summary of the Bundesbank Monthly Report on the housing market.
Used for: Higher interest rates made buying unaffordable for many, and housing demand shifted towards the rental market.
Amaral, F., Jungwirth, P., Zdrzalek, J. & Zetzmann, S. (2025). Dokumentation für den Mietpreisindex (GREIX). Kiel Institut für Weltwirtschaft, 12 June 2025.
Used for: Asking rents in 37 cities from VALUE listing data, adjusted by hedonic regression for 21 characteristics including floor area, building age, rooms, condition, fittings and postcode.
Bundesinstitut für Bau-, Stadt- und Raumforschung (BBSR) (2025). Wohnungsmieten. BBSR Fachbeitrag, Wohnungs- und Immobilienmarktbeobachtung.
Used for: New-lease rents are well above existing rents because existing rents are adjusted to the market less often and rises for sitting tenants are capped by law.
Sagner, P. & Voigtländer, M. (2026). In Großstädten: Mietangebote seit 2022 um bis zu 57 Prozent eingebrochen. Institut der deutschen Wirtschaft (IW), press release, July 2026.
Used for: When new-lease rents are high, households stay longer, including in flats that no longer suit them.
Gohl, N. (2019). House prices and spatial mobility: Lock-in effects on the German rental market. Beiträge zur Jahrestagung des Vereins für Socialpolitik 2019, ZBW.
Used for: Academic study of the lock-in effect: the gap between sitting-tenant and new-lease rents reduces renters' mobility.
Deutscher Mieterbund (2025). Betriebskostenspiegel für Deutschland, Abrechnungsjahr 2024. Deutscher Mieterbund, 18 December 2025.
Used for: Running costs averaged 2.67 € per m² and month in 2024, on top of the cold rent.
Sächsische Staatsregierung (2022). Sächsische Mietpreisbegrenzungsverordnung (SächsMPBVO), Begründung zu Indikator 5. REVOSax, 31 May 2022.
Used for: Citing the BBSR, the normal turnover vacancy a market needs is mostly given as 2 to 3% in the literature, sometimes 3 to 5%.
Bürgerliches Gesetzbuch (2025). § 556d BGB, Abs. 2: Gebiete mit angespannten Wohnungsmärkten. German Civil Code.
Used for: German law names low vacancy with high demand, and population growth without enough new building, as signs of a tight housing market.
Statistisches Bundesamt (Destatis) (2024). Zensus 2022: 4,3 % aller Wohnungen stehen leer. Press release No. 46, 4 July 2024.
Used for: Census vacancy figures for May 2022, including flats that could be occupied within three months.
Eurostat, ILO, IMF, OECD, UNECE & World Bank (2013). Handbook on Residential Property Prices Indices (RPPIs). Publications Office of the European Union.
Used for: Standard reference for hedonic quality adjustment in housing price indices.
Ke, G., Meng, Q., Finley, T., Wang, T., Chen, W., Ma, W., Ye, Q. & Liu, T.-Y. (2017). LightGBM: A Highly Efficient Gradient Boosting Decision Tree. Advances in Neural Information Processing Systems 30 (NeurIPS 2017).
Used for: The gradient boosting library used for the forecasts.
Koenker, R. & Bassett, G. (1978). Regression Quantiles. Econometrica 46(1), 33–50.
Used for: Quantile regression: predicting a range (10th to 90th percentile) instead of a single value.
Romano, Y., Patterson, E. & Candès, E. J. (2019). Conformalized Quantile Regression. Advances in Neural Information Processing Systems 32 (NeurIPS 2019).
Used for: Calibrating quantile ranges so that they contain the stated share of real outcomes.
Hyndman, R. J. & Athanasopoulos, G. (2021). Forecasting: Principles and Practice, 3rd edition, section 5.10 Time series cross-validation. OTexts, Melbourne.
Used for: Rolling-origin back-testing: train only on data before each cut-off and score the forecast on what came after.
Iglewicz, B. & Hoaglin, D. C. (1993). How to Detect and Handle Outliers (as summarised in the NIST/SEMATECH e-Handbook of Statistical Methods, 1.3.5.17). ASQC Quality Press.
Used for: Modified z-scores based on the median absolute deviation, with |z| above 3.5 flagged as a likely outlier.
United Nations, Department of Economic and Social Affairs, Population Division (2018). World Urbanization Prospects: The 2018 Revision. Key facts. United Nations, New York.
Used for: Mumbai is among the world's largest cities, with close to 20 million inhabitants.
Bhagat, R. B. & Jones, G. W. (2016). Demographic Dynamics of Mega-Urban Regions: The Case of Mumbai. Asia Research Institute Working Paper No. 201, National University of Singapore.
Used for: Census 2011: Greater Mumbai had 12.47 million people, and 41.8% (5.2 million) lived in slums.
Statistisches Bundesamt (Destatis) (2025). Wohnkostenanteil und Wohnkostenüberbelastung (EU-SILC). Destatis table, Mikrozensus / EU-SILC.
Used for: In 2025, 11.2% of the population spent more than 40% of their income on housing; among people at risk of poverty it was 35.0%.
Holm, A., Regnault, V., Sprengholz, M. & Stephan, M. (2021). Muster sozialer Ungleichheit der Wohnversorgung in deutschen Großstädten. Hans-Böckler-Stiftung, Working Paper Forschungsförderung No. 222.
Used for: Almost 13% of tenant households in Germany's 77 big cities have less than the subsistence minimum left after paying rent.
About
ImmoDash is an independent portfolio project by Zoeb Ali Khan: a full data platform from raw government files to tested models, an API and this website, maintained automatically. It is not affiliated with any of the data providers.
- Data engineering: medallion warehouse with dbt, DuckDB and PostgreSQL, Prefect orchestration
- Geo analytics: 380,000+ census grid cells mapped to all 400 districts
- Machine learning: LightGBM quantile forecasts, conformal calibration, anomaly detection
- Applied AI: grounded LLM summaries with automatic fact checking
- Product: FastAPI, Next.js, Plotly Dash, CI/CD with GitHub Actions
Sources
| Dataset | Licence |
|---|---|
| Statistische Ämter des Bundes und der Länder, Zensus 2022 (table 4000W-0011) | Datenlizenz Deutschland - Namensnennung - Version 2.0 |
| Statistische Ämter des Bundes und der Länder, Zensus 2022 (table 4000W-0002) | Datenlizenz Deutschland - Namensnennung - Version 2.0 |
| Statistische Ämter des Bundes und der Länder, Zensus 2022 (table 4000W-0009) | Datenlizenz Deutschland - Namensnennung - Version 2.0 |
| Statistische Ämter des Bundes und der Länder, Zensus 2022 (table 4000W-0004, Bezirke) | Datenlizenz Deutschland - Namensnennung - Version 2.0 |
| OpenStreetMap postcode boundaries via yetzt/postleitzahlen (release 2026.02) | ODbL 1.0 (© OpenStreetMap contributors); the derived postcode rent table is shared under ODbL |
| Statistische Ämter des Bundes und der Länder, Zensus 2022 Gitterzellen (100 m / 1 km) | Datenlizenz Deutschland - Namensnennung - Version 2.0 |
| Arbeitskreis VGR der Länder, Reihe 2 Band 3 (Berechnungsstand 2024) | Datenlizenz Deutschland - Namensnennung - Version 2.0 |
| GREIX Mietpreisindex, Kiel Institut für Weltwirtschaft | Free use with attribution (GREIX, Kiel Institut / VALUE Marktdaten) |
| GREIX Miet- und Transaktionspreisindex, Kiel Institut für Weltwirtschaft | Free use with attribution (GREIX, Kiel Institut) |
| Deutsche Bundesbank, MFI interest rate statistics (SUD131Z) | Deutsche Bundesbank, free use with attribution |
| Bundesamt für Kartographie und Geodäsie via Praesklepios/geoGermany | © GeoBasis-DE / BKG (VG5000, Stand 01.01.2021), dl-de/by-2-0 |