If you sell to the public sector in Germany, the clock starts the moment a tender is published. So I wanted a simple number: how many days are there between publication and the bid deadline?
I took two daily snapshots (8 and 9 November 2026) of the public tender RSS feed on service.bund.de, the federal portal that also aggregates many state and municipal contracting bodies. After de-duplication that is 195 tenders published between 6 and 9 November. 187 of them state an offer deadline (Angebotsfrist) in the feed.
Disclosure: I built the German Public Tenders actor mentioned at the end. The analysis below uses only the free public RSS feed.
The result
| Days to bid deadline | Tenders | Share |
|---|---|---|
| up to 14 | 16 | 9% |
| 15–21 | 24 | 13% |
| 22–30 | 88 | 47% |
| 31–45 | 56 | 30% |
| over 45 | 3 | 2% |
- Median: 30 days. Shortest: 5 days. Longest: 64 days.
- 40 tenders (21%) give you three weeks or less. That is roughly one in five.
What this means in practice: if you check the portal once a month, you will miss most of the short ones entirely, and you will see the typical 30-day tender with only a week or two left. If public customers matter to you, the check has to be daily, or at least a few times a week.
Is construction faster than IT?
I grouped the titles with a crude keyword match (construction terms like Sanierung, Dach, Elektro, Los 3; IT terms like Software, Lizenz, Server). It is rough, so treat it as a hint, not a finding:
| Group (by title keywords) | Tenders with deadline | Median days | ≤ 21 days |
|---|---|---|---|
| Construction | 77 | 30 | 16 |
| Supplies | 18 | 30 | 3 |
| Services | 13 | 30 | 4 |
| IT / software | 10 | 29.5 | 2 |
| Other / unclear | 69 | 29 | 15 |
The medians are almost identical. In this sample, the type of work does not predict the deadline; the individual contracting body does.
Where the tenders come from
German postal codes start with a zone digit, which gives a quick regional picture without parsing addresses:
| Postal zone | Rough region | Tenders |
|---|---|---|
| 5 | Cologne, Bonn, Aachen, Koblenz, Trier | 41 |
| 0 | Saxony, East Thuringia, south Saxony-Anhalt | 25 |
| 4 | Ruhr area, Düsseldorf, Münsterland | 24 |
| 3 | Hanover, North Hesse, parts of Saxony-Anhalt | 19 |
| 1 | Berlin, Brandenburg, Mecklenburg-Vorpommern | 12 |
| 9 | Nuremberg, North Bavaria, most of Thuringia | 11 |
| 2 | Hamburg, Bremen, Schleswig-Holstein | 10 |
| 6 | Frankfurt, Saarland, Mannheim | 8 |
| 7 | Stuttgart, Karlsruhe | 6 |
| 8 | Munich, South Bavaria | 4 |
Careful with this one. Several German states run their own procurement portals, so a low count here means "few of this region's tenders flow into this feed", not "few tenders in this region". If you only watch one portal, you only see part of the market.
Repeat it yourself
The feed is public and needs no key. This script fetches the newest 100 entries and computes the same distribution:
import re, statistics, email.utils, datetime as dt, html
import httpx
FEED = ("https://www.service.bund.de/Content/DE/Ausschreibungen/Suche/Formular.html"
"?nn=4641482&type=0&resultsPerPage=100&sortOrder=dateOfIssue_dt+desc&jobsrss=true")
xml = httpx.get(FEED, timeout=60, headers={"User-Agent": "tender-deadline-study/1.0"}).text
days = []
for item in re.findall(r"<item>(.*?)</item>", xml, re.S):
pub = re.search(r"<pubDate>(.*?)</pubDate>", item).group(1)
desc = html.unescape(re.search(r"<description>(.*?)</description>", item, re.S).group(1))
m = re.search(r"Angebotsfrist:\s*<strong>(\d\d\.\d\d\.\d{4})", desc)
if not m:
continue
published = email.utils.parsedate_to_datetime(pub).date()
deadline = dt.datetime.strptime(m.group(1), "%d.%m.%Y").date()
days.append((deadline - published).days)
print(len(days), "tenders, median", statistics.median(days), "days")
print("3 weeks or less:", sum(d <= 21 for d in days))
Run it once a day and store the result, and after a month you have a much better sample than my four days.
Limits
- Small sample. Four publication days, one portal. The shape (most deadlines around 30 days, a fat tail of short ones) is plausible, the exact percentages are not a statistic for all of Germany.
-
Feed dates.
pubDateis when the notice entered the feed, which can be a day after the official publication. - Missing deadlines. 8 of 195 entries had no offer deadline in the feed, only an end of publication.
- This is not legal or procurement advice. The official notice is what counts.
Try it
If you want the deadline, contracting authority, state, procedure type and CPV codes as clean JSON instead of parsing HTML in RSS descriptions, the German Public Tenders actor does that for $0.002 per tender. For EU-wide notices there is the EU Tenders (TED) API at the same price, and a ready-made n8n workflow that turns both into a daily Slack digest lives in our data-recipes repo.
Question for anyone who bids on public contracts: what is the shortest realistic time you need from "we found it" to a complete bid? I am trying to decide where to set the "urgent" threshold in the alert.

Top comments (0)