{"id":9367,"date":"2026-08-12T09:20:00","date_gmt":"2026-08-12T07:20:00","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/?p=9367"},"modified":"2026-09-24T23:33:30","modified_gmt":"2026-09-24T21:33:30","slug":"google-ads-data-retention-37-months-of-performance-data-and-a-resumable","status":"publish","type":"post","link":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/","title":{"rendered":"Google Ads Data Retention: 37 Months of Performance Data and a Resumable Backfill Job"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Since 1 June 2026, Google Ads data has an expiry date. Performance data is kept for 37 months, account change history for 11 years, Reach and Frequency data for 3 years. Today is 10 August 2026, so the oldest performance day still available is 10 July 2023, and that line moves forward by one day every day. Where the reporting history lives only inside Google Ads, a day of it disappears quietly every day. This article does the arithmetic, corrects the numbers that are being misquoted alongside it, and builds a resumable backfill job that moves everything above the line into a warehouse under local control.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. What the retention page actually says<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Three windows are documented, and only three:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>37 months<\/strong> for performance data.<\/li>\n<li><strong>11 years<\/strong> for the history of account changes.<\/li>\n<li><strong>3 years<\/strong> for Reach and Frequency.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Most write-ups of this change carry three further numbers along with it: 36 months for the GA Data API, 24 months for the BigQuery Data Transfer Service, 24 months for DV360 and CM360. Those values do not appear on the Google Ads help page that announced the retention windows. They are undocumented as far as this announcement goes, and passing them on as if they were part of it is how a rumour becomes a planning assumption. Plan against the three values above. A retention figure for GA4, for BigQuery transfers or for DV360 and CM360 belongs taken from that product&#8217;s own documentation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One detail is easy to misread: 37 months is longer than three years. Reach and Frequency therefore expires about a month <em>before<\/em> the performance data covering the same campaigns. Where both are backed up, R&amp;F has the tighter deadline, not the looser one.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Work out the actual deadline, then find what is already gone<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The boundary is a rolling one, not a single cut that happened in June. Compute it rather than remembering it:<\/p>\n\n\n<figure style=\"--cbb-digits:1\" class=\"cbb cbb--wrap cbb--numbers wp-block-code-beautifier-block-code\" data-lang=\"python\"><figcaption class=\"cbb-head\"><span class=\"cbb-lang\">Python<\/span><span class=\"cbb-actions\"><button type=\"button\" class=\"cbb-button cbb-button--wrap\" data-cbb-action=\"wrap\" aria-pressed=\"true\" title=\"Wrap long lines\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M2 4h12M2 8h9.5a2.5 2.5 0 0 1 0 5H8m0 0 1.5-1.5M8 13l1.5 1.5M2 12h3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg><span class=\"cbb-sr\">Wrap long lines<\/span><\/button><button type=\"button\" class=\"cbb-button cbb-button--copy\" data-cbb-action=\"copy\" data-cbb-done=\"Copied\" data-cbb-failed=\"Press Ctrl+C to copy\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><rect x=\"5.5\" y=\"5.5\" width=\"8\" height=\"8.5\" rx=\"1.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><path d=\"M10.5 3.5V3A1.5 1.5 0 0 0 9 1.5H4A1.5 1.5 0 0 0 2.5 3v6.5A1.5 1.5 0 0 0 4 11h.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><\/svg><span class=\"cbb-button-label\" aria-live=\"polite\">Copy<\/span><\/button><\/span><\/figcaption><pre class=\"cbb-pre\" tabindex=\"0\"><code class=\"cbb-code language-python\" style=\"counter-reset:cbb-line 0;\"><span class=\"cbb-line\"><span class=\"cbb-keyword\">from<\/span> datetime <span class=\"cbb-keyword\">import<\/span> date\n<\/span><span class=\"cbb-line\"><span class=\"cbb-keyword\">from<\/span> dateutil.relativedelta <span class=\"cbb-keyword\">import<\/span> relativedelta\n<\/span><span class=\"cbb-line\">\n<\/span><span class=\"cbb-line\">today = <span class=\"cbb-function\">date<\/span>(<span class=\"cbb-number\">2026<\/span>, <span class=\"cbb-number\">8<\/span>, <span class=\"cbb-number\">10<\/span>)\n<\/span><span class=\"cbb-line\"><span class=\"cbb-function\">print<\/span>(today - <span class=\"cbb-function\">relativedelta<\/span>(months=<span class=\"cbb-number\">37<\/span>))  <span class=\"cbb-comment\"># performance      2023-07-10<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-function\">print<\/span>(today - <span class=\"cbb-function\">relativedelta<\/span>(years=<span class=\"cbb-number\">3<\/span>))    <span class=\"cbb-comment\"># reach, frequency 2023-08-10<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-function\">print<\/span>(today - <span class=\"cbb-function\">relativedelta<\/span>(years=<span class=\"cbb-number\">11<\/span>))   <span class=\"cbb-comment\"># change history   2015-08-10<\/span><\/span><\/code><\/pre><\/figure>\n\n\n<p class=\"wp-block-paragraph\">Anything dated before 10 July 2023 is already unrecoverable through the API. Tomorrow that becomes 11 July 2023. Before writing any export code, it pays to establish how much of the still-available range is actually held locally. Against a Postgres warehouse with a daily table:<\/p>\n\n\n<figure style=\"--cbb-digits:1\" class=\"cbb cbb--wrap cbb--numbers wp-block-code-beautifier-block-code\" data-lang=\"sql\"><figcaption class=\"cbb-head\"><span class=\"cbb-lang\">SQL<\/span><span class=\"cbb-actions\"><button type=\"button\" class=\"cbb-button cbb-button--wrap\" data-cbb-action=\"wrap\" aria-pressed=\"true\" title=\"Wrap long lines\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M2 4h12M2 8h9.5a2.5 2.5 0 0 1 0 5H8m0 0 1.5-1.5M8 13l1.5 1.5M2 12h3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg><span class=\"cbb-sr\">Wrap long lines<\/span><\/button><button type=\"button\" class=\"cbb-button cbb-button--copy\" data-cbb-action=\"copy\" data-cbb-done=\"Copied\" data-cbb-failed=\"Press Ctrl+C to copy\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><rect x=\"5.5\" y=\"5.5\" width=\"8\" height=\"8.5\" rx=\"1.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><path d=\"M10.5 3.5V3A1.5 1.5 0 0 0 9 1.5H4A1.5 1.5 0 0 0 2.5 3v6.5A1.5 1.5 0 0 0 4 11h.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><\/svg><span class=\"cbb-button-label\" aria-live=\"polite\">Copy<\/span><\/button><\/span><\/figcaption><pre class=\"cbb-pre\" tabindex=\"0\"><code class=\"cbb-code language-sql\" style=\"counter-reset:cbb-line 0;\"><span class=\"cbb-line\"><span class=\"cbb-keyword\">WITH<\/span> expected <span class=\"cbb-keyword\">AS<\/span> (\n<\/span><span class=\"cbb-line\">  <span class=\"cbb-keyword\">SELECT<\/span> <span class=\"cbb-function\">generate_series<\/span>(<span class=\"cbb-type\">DATE<\/span> <span class=\"cbb-string\">'2023-07-10'<\/span>, CURRENT_DATE - <span class=\"cbb-number\">1<\/span>, <span class=\"cbb-keyword\">INTERVAL<\/span> <span class=\"cbb-string\">'1 day'<\/span>)::<span class=\"cbb-type\">date<\/span> <span class=\"cbb-keyword\">AS<\/span> d\n<\/span><span class=\"cbb-line\">)\n<\/span><span class=\"cbb-line\"><span class=\"cbb-keyword\">SELECT<\/span> <span class=\"cbb-function\">count<\/span>(*) <span class=\"cbb-keyword\">AS<\/span> missing_days, <span class=\"cbb-function\">min<\/span>(e.d) <span class=\"cbb-keyword\">AS<\/span> oldest_gap, <span class=\"cbb-function\">max<\/span>(e.d) <span class=\"cbb-keyword\">AS<\/span> newest_gap\n<\/span><span class=\"cbb-line\"><span class=\"cbb-keyword\">FROM<\/span> expected e\n<\/span><span class=\"cbb-line\"><span class=\"cbb-keyword\">LEFT<\/span> <span class=\"cbb-keyword\">JOIN<\/span> ads_daily a <span class=\"cbb-keyword\">ON<\/span> a.day = e.d\n<\/span><span class=\"cbb-line\"><span class=\"cbb-keyword\">WHERE<\/span> a.day <span class=\"cbb-keyword\">IS<\/span> <span class=\"cbb-constant\">NULL<\/span>;<\/span><\/code><\/pre><\/figure>\n\n\n<p class=\"wp-block-paragraph\">Run the same query with the window start set to the earliest expected day. Everything it reports below 2023-07-10 is a permanent hole; everything above it is still recoverable.<\/p>\n\n\n\n<figure class=\"lw-diagram\">\n<img decoding=\"async\" src=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/diagrams\/hand-adsretention-en.png\" width=\"1120\" height=\"660\" loading=\"lazy\" alt=\"A timeline with a 37-month retention window whose left edge moves daily, older data falling out into a self-hosted warehouse\">\n<figcaption>Three limits, one moving edge. Everything to the left of it has already left Google Ads, so the export job is only useful while it runs ahead of the edge rather than behind it.<\/figcaption>\n<\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">3. A backfill job that resumes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I am not going to print a GAQL field list here, because the right one is the one already in use. Take the resource, the date segment and the selected fields straight out of the report running today, put them in a config file, and let the job own nothing but the date window:<\/p>\n\n\n<figure style=\"--cbb-digits:1\" class=\"cbb cbb--wrap cbb--numbers wp-block-code-beautifier-block-code\" data-lang=\"json\"><figcaption class=\"cbb-head\"><span class=\"cbb-lang\">JSON<\/span><span class=\"cbb-actions\"><button type=\"button\" class=\"cbb-button cbb-button--wrap\" data-cbb-action=\"wrap\" aria-pressed=\"true\" title=\"Wrap long lines\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M2 4h12M2 8h9.5a2.5 2.5 0 0 1 0 5H8m0 0 1.5-1.5M8 13l1.5 1.5M2 12h3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg><span class=\"cbb-sr\">Wrap long lines<\/span><\/button><button type=\"button\" class=\"cbb-button cbb-button--copy\" data-cbb-action=\"copy\" data-cbb-done=\"Copied\" data-cbb-failed=\"Press Ctrl+C to copy\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><rect x=\"5.5\" y=\"5.5\" width=\"8\" height=\"8.5\" rx=\"1.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><path d=\"M10.5 3.5V3A1.5 1.5 0 0 0 9 1.5H4A1.5 1.5 0 0 0 2.5 3v6.5A1.5 1.5 0 0 0 4 11h.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><\/svg><span class=\"cbb-button-label\" aria-live=\"polite\">Copy<\/span><\/button><\/span><\/figcaption><pre class=\"cbb-pre\" tabindex=\"0\"><code class=\"cbb-code language-json\" style=\"counter-reset:cbb-line 0;\"><span class=\"cbb-line\">{\n<\/span><span class=\"cbb-line\">  <span class=\"cbb-attr\">\"customer_id\"<\/span>: <span class=\"cbb-string\">\"1234567890\"<\/span>,\n<\/span><span class=\"cbb-line\">  <span class=\"cbb-attr\">\"dsn\"<\/span>: <span class=\"cbb-string\">\"postgresql:\/\/ads@localhost\/warehouse\"<\/span>,\n<\/span><span class=\"cbb-line\">  <span class=\"cbb-attr\">\"resource\"<\/span>:   <span class=\"cbb-string\">\"&lt;the resource your existing report reads&gt;\"<\/span>,\n<\/span><span class=\"cbb-line\">  <span class=\"cbb-attr\">\"date_field\"<\/span>: <span class=\"cbb-string\">\"&lt;the date segment that report groups by&gt;\"<\/span>,\n<\/span><span class=\"cbb-line\">  <span class=\"cbb-attr\">\"fields\"<\/span>:     &#91;<span class=\"cbb-string\">\"&lt;field 1&gt;\"<\/span>, <span class=\"cbb-string\">\"&lt;field 2&gt;\"<\/span>&#93;,\n<\/span><span class=\"cbb-line\">  <span class=\"cbb-attr\">\"query_template\"<\/span>: <span class=\"cbb-string\">\"SELECT {fields} FROM {resource} WHERE {date_field} BETWEEN '{start}' AND '{end}'\"<\/span>,\n<\/span><span class=\"cbb-line\">  <span class=\"cbb-attr\">\"oldest_wanted\"<\/span>: <span class=\"cbb-string\">\"2019-01-01\"<\/span>\n<\/span><span class=\"cbb-line\">}<\/span><\/code><\/pre><\/figure>\n\n\n<p class=\"wp-block-paragraph\">The runner fetches exactly one window per invocation and records it. State is four columns: <code>customer_id<\/code>, <code>window_start<\/code>, <code>window_end<\/code>, <code>rows<\/code>, written in the same transaction as the data, so a crash simply repeats the window.<\/p>\n\n\n<figure style=\"--cbb-digits:2\" class=\"cbb cbb--wrap cbb--numbers wp-block-code-beautifier-block-code\" data-lang=\"python\"><figcaption class=\"cbb-head\"><span class=\"cbb-lang\">Python<\/span><span class=\"cbb-actions\"><button type=\"button\" class=\"cbb-button cbb-button--wrap\" data-cbb-action=\"wrap\" aria-pressed=\"true\" title=\"Wrap long lines\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M2 4h12M2 8h9.5a2.5 2.5 0 0 1 0 5H8m0 0 1.5-1.5M8 13l1.5 1.5M2 12h3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg><span class=\"cbb-sr\">Wrap long lines<\/span><\/button><button type=\"button\" class=\"cbb-button cbb-button--copy\" data-cbb-action=\"copy\" data-cbb-done=\"Copied\" data-cbb-failed=\"Press Ctrl+C to copy\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><rect x=\"5.5\" y=\"5.5\" width=\"8\" height=\"8.5\" rx=\"1.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><path d=\"M10.5 3.5V3A1.5 1.5 0 0 0 9 1.5H4A1.5 1.5 0 0 0 2.5 3v6.5A1.5 1.5 0 0 0 4 11h.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><\/svg><span class=\"cbb-button-label\" aria-live=\"polite\">Copy<\/span><\/button><\/span><\/figcaption><pre class=\"cbb-pre\" tabindex=\"0\"><code class=\"cbb-code language-python\" style=\"counter-reset:cbb-line 0;\"><span class=\"cbb-line\"><span class=\"cbb-keyword\">import<\/span> json\n<\/span><span class=\"cbb-line\"><span class=\"cbb-keyword\">from<\/span> datetime <span class=\"cbb-keyword\">import<\/span> date, timedelta\n<\/span><span class=\"cbb-line\"><span class=\"cbb-keyword\">from<\/span> dateutil.relativedelta <span class=\"cbb-keyword\">import<\/span> relativedelta\n<\/span><span class=\"cbb-line\"><span class=\"cbb-keyword\">import<\/span> psycopg\n<\/span><span class=\"cbb-line\">\n<\/span><span class=\"cbb-line\">CFG, CHUNK = json.<span class=\"cbb-function\">load<\/span>(<span class=\"cbb-function\">open<\/span>(<span class=\"cbb-string\">\"\/etc\/ads-backfill\/config.json\"<\/span>)), <span class=\"cbb-function\">timedelta<\/span>(days=<span class=\"cbb-number\">7<\/span>)\n<\/span><span class=\"cbb-line\">CID = CFG&#91;<span class=\"cbb-string\">\"customer_id\"<\/span>&#93;\n<\/span><span class=\"cbb-line\">\n<\/span><span class=\"cbb-line\"><span class=\"cbb-keyword\">def<\/span> <span class=\"cbb-function\">next_window<\/span>(cur):\n<\/span><span class=\"cbb-line\">    cur.<span class=\"cbb-function\">execute<\/span>(<span class=\"cbb-string\">\"SELECT max(window_end) FROM backfill_state WHERE customer_id = %s\"<\/span>, (CID,))\n<\/span><span class=\"cbb-line\">    (last,) = cur.<span class=\"cbb-function\">fetchone<\/span>()\n<\/span><span class=\"cbb-line\">    floor = <span class=\"cbb-function\">max<\/span>(date.<span class=\"cbb-function\">today<\/span>() - <span class=\"cbb-function\">relativedelta<\/span>(months=<span class=\"cbb-number\">37<\/span>),\n<\/span><span class=\"cbb-line\">                date.<span class=\"cbb-function\">fromisoformat<\/span>(CFG&#91;<span class=\"cbb-string\">\"oldest_wanted\"<\/span>&#93;))\n<\/span><span class=\"cbb-line\">    start = last + <span class=\"cbb-function\">timedelta<\/span>(days=<span class=\"cbb-number\">1<\/span>) <span class=\"cbb-keyword\">if<\/span> last <span class=\"cbb-keyword\">else<\/span> floor\n<\/span><span class=\"cbb-line\">    <span class=\"cbb-keyword\">if<\/span> start &lt; floor:                    <span class=\"cbb-comment\"># job stalled, those days expired<\/span>\n<\/span><span class=\"cbb-line\">        cur.<span class=\"cbb-function\">execute<\/span>(<span class=\"cbb-string\">\"INSERT INTO backfill_lost VALUES (%s, %s, %s)\"<\/span>,\n<\/span><span class=\"cbb-line\">                    (CID, start, floor - <span class=\"cbb-function\">timedelta<\/span>(days=<span class=\"cbb-number\">1<\/span>)))\n<\/span><span class=\"cbb-line\">        start = floor\n<\/span><span class=\"cbb-line\">    end = <span class=\"cbb-function\">min<\/span>(start + CHUNK - <span class=\"cbb-function\">timedelta<\/span>(days=<span class=\"cbb-number\">1<\/span>), date.<span class=\"cbb-function\">today<\/span>() - <span class=\"cbb-function\">timedelta<\/span>(days=<span class=\"cbb-number\">1<\/span>))\n<\/span><span class=\"cbb-line\">    <span class=\"cbb-keyword\">return<\/span> (start, end) <span class=\"cbb-keyword\">if<\/span> start &lt;= end <span class=\"cbb-keyword\">else<\/span> <span class=\"cbb-constant\">None<\/span>\n<\/span><span class=\"cbb-line\">\n<\/span><span class=\"cbb-line\"><span class=\"cbb-keyword\">with<\/span> psycopg.<span class=\"cbb-function\">connect<\/span>(CFG&#91;<span class=\"cbb-string\">\"dsn\"<\/span>&#93;) <span class=\"cbb-keyword\">as<\/span> conn, conn.<span class=\"cbb-function\">cursor<\/span>() <span class=\"cbb-keyword\">as<\/span> cur:\n<\/span><span class=\"cbb-line\">    win = <span class=\"cbb-function\">next_window<\/span>(cur)\n<\/span><span class=\"cbb-line\">    <span class=\"cbb-keyword\">if<\/span> win:\n<\/span><span class=\"cbb-line\">        start, end = win\n<\/span><span class=\"cbb-line\">        rows = <span class=\"cbb-function\">run_report<\/span>(CID, CFG&#91;<span class=\"cbb-string\">\"query_template\"<\/span>&#93;.<span class=\"cbb-function\">format<\/span>(\n<\/span><span class=\"cbb-line\">            fields=<span class=\"cbb-string\">\", \"<\/span>.<span class=\"cbb-function\">join<\/span>(CFG&#91;<span class=\"cbb-string\">\"fields\"<\/span>&#93;), resource=CFG&#91;<span class=\"cbb-string\">\"resource\"<\/span>&#93;,\n<\/span><span class=\"cbb-line\">            date_field=CFG&#91;<span class=\"cbb-string\">\"date_field\"<\/span>&#93;, start=start, end=end))\n<\/span><span class=\"cbb-line\">        cur.<span class=\"cbb-function\">executemany<\/span>(CFG&#91;<span class=\"cbb-string\">\"insert_sql\"<\/span>&#93;, rows)\n<\/span><span class=\"cbb-line\">        cur.<span class=\"cbb-function\">execute<\/span>(<span class=\"cbb-string\">\"INSERT INTO backfill_state VALUES (%s, %s, %s, %s, now())\"<\/span>,\n<\/span><span class=\"cbb-line\">                    (CID, start, end, <span class=\"cbb-function\">len<\/span>(rows)))\n<\/span><span class=\"cbb-line\">        conn.<span class=\"cbb-function\">commit<\/span>()<\/span><\/code><\/pre><\/figure>\n\n\n<p class=\"wp-block-paragraph\"><code>run_report<\/code> is the existing API wrapper, whichever client library it wraps. Everything else in the file works on the local side of the line: local config, local table, local transaction boundary.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Cron, ordering, and the loss ledger<\/h2>\n\n\n<figure style=\"--cbb-digits:1\" class=\"cbb cbb--wrap wp-block-code-beautifier-block-code\" data-lang=\"bash\"><figcaption class=\"cbb-head\"><span class=\"cbb-lang\">Shell<\/span><span class=\"cbb-actions\"><button type=\"button\" class=\"cbb-button cbb-button--wrap\" data-cbb-action=\"wrap\" aria-pressed=\"true\" title=\"Wrap long lines\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M2 4h12M2 8h9.5a2.5 2.5 0 0 1 0 5H8m0 0 1.5-1.5M8 13l1.5 1.5M2 12h3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg><span class=\"cbb-sr\">Wrap long lines<\/span><\/button><button type=\"button\" class=\"cbb-button cbb-button--copy\" data-cbb-action=\"copy\" data-cbb-done=\"Copied\" data-cbb-failed=\"Press Ctrl+C to copy\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><rect x=\"5.5\" y=\"5.5\" width=\"8\" height=\"8.5\" rx=\"1.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><path d=\"M10.5 3.5V3A1.5 1.5 0 0 0 9 1.5H4A1.5 1.5 0 0 0 2.5 3v6.5A1.5 1.5 0 0 0 4 11h.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><\/svg><span class=\"cbb-button-label\" aria-live=\"polite\">Copy<\/span><\/button><\/span><\/figcaption><pre class=\"cbb-pre\" tabindex=\"0\"><code class=\"cbb-code language-bash\" style=\"counter-reset:cbb-line 0;\"><span class=\"cbb-line\"><span class=\"cbb-comment\"># \/etc\/cron.d\/ads-backfill \u2014 one window per hour, oldest first<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-number\">7<\/span> * * * * ads \/opt\/ads-backfill\/.venv\/bin\/<span class=\"cbb-function\">python<\/span> \/opt\/ads-backfill\/backfill.py <span class=\"cbb-operator\">&gt;&gt;<\/span> \/var\/log\/ads-backfill.log <span class=\"cbb-number\">2<\/span><span class=\"cbb-operator\">&gt;<\/span>&amp;<span class=\"cbb-number\">1<\/span><\/span><\/code><\/pre><\/figure>\n\n\n<p class=\"wp-block-paragraph\">Two things about that job are deliberate. It walks <strong>forward from the boundary<\/strong>, not backward from today, because the oldest data is the only data with a deadline; recent days can wait. And when it finds that the boundary has overtaken its own progress, it does not silently skip the gap, it writes the span into <code>backfill_lost<\/code>. That table is the honest answer to &#8220;which periods do we no longer have&#8221;, and it is worth putting on a dashboard next to the gap query from section 2.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The arithmetic is comfortable. From 10 July 2023 to yesterday is 1,126 days, which is 161 windows of seven days. At one window per hour that is under seven days of wall clock, during which the boundary advances by seven days: that is 168 days of history gained for every one lost. Once the backlog is closed, the same job keeps the tail topped up and costs one API call per hour.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Summary<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The result is a boundary that gets computed rather than remembered, a query that names which days inside the still-available window are missing from the warehouse, and a single-window runner that resumes cleanly after a crash and clamps itself to the current cutoff. On top of that come an hourly cron entry and a ledger of the periods that are already beyond recovery. The whole backlog from 10 July 2023 onward closes in about a week of unattended running, after which the job becomes maintenance.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The gain is that the reporting history stops being someone else&#8217;s retention policy. Year-over-year comparisons, seasonality models and attribution rebuilds all need data older than 37 months eventually, and after 1 June 2026 the only copy that will still exist is the one kept locally. Confirm the three documented windows in the primary source and ignore the extra figures circulating with them: <a href=\"https:\/\/support.google.com\/google-ads\/answer\/15188209\">Google Ads data retention policy<\/a>.<\/p>\n\n\n<div class=\"lw-faq\">\n<h2>Questions and answers<\/h2>\n\n<h3>Are the extra retention figures circulating with this change wrong, or are they only attached to the wrong announcement?<\/h3>\n<p>They are attached to the wrong announcement, and the distinction matters more than it sounds.<\/p>\n<p>Three windows are documented on the Google Ads retention page and only three: 37 months for performance data, 11 years for account change history, 3 years for Reach and Frequency. Everything else that circulates with this change, namely 36 months for the GA Data API, 24 months for the BigQuery Data Transfer Service and 24 months for DV360 and CM360, is absent from that page.<\/p>\n<p>Some of those figures may be accurate for their own products. The problem is the provenance: a number carried over from a different announcement inherits an authority it was never given, and nobody rechecks it afterwards because it arrived inside a well-sourced article. Taking each retention figure from its own product&#8217;s documentation costs a few minutes and removes the whole class of error.<\/p>\n<\/div>\n\n<div class=\"lw-quellen\">\n<h2>Sources<\/h2>\n<ul>\n<li><a href=\"https:\/\/support.google.com\/google-ads\/answer\/15188209\" target=\"_blank\" rel=\"noopener noreferrer\">Google Ads Data Retention Policy<\/a><\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>Google Ads now deletes performance data after 37 months, and the line moves daily; here is the arithmetic, a resumable backfill job, and the numbers people are wrongly quoting.<\/p>\n","protected":false},"author":1,"featured_media":15125,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[91106,91333,91386,91288],"class_list":["post-9367","post","type-post","status-publish","format-standard","hentry","category-digital-marketing","tag-automation","tag-bigquery","tag-marketing-cyfrowy-pl","tag-google-ads"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Google Ads Data Retention: 37 Months of Performance Data and a Resumable Backfill Job | Lukas Wojcik<\/title>\n<meta name=\"description\" content=\"Archive Google Ads data: calculate retention boundaries, resume historical exports and track losses in a backfill ledger.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Google Ads Data Retention: 37 Months of Performance Data and a Resumable Backfill Job | Lukas Wojcik\" \/>\n<meta property=\"og:description\" content=\"Archive Google Ads data: calculate retention boundaries, resume historical exports and track losses in a backfill ledger.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-12T07:20:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-24T21:33:30+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-9367-google-ads-data-retention-37-months--n.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Lukas Wojcik\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Lukas Wojcik\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\\\/\"},\"author\":{\"name\":\"Lukas Wojcik\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"headline\":\"Google Ads Data Retention: 37 Months of Performance Data and a Resumable Backfill Job\",\"datePublished\":\"2026-08-12T07:20:00+00:00\",\"dateModified\":\"2026-09-24T21:33:30+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\\\/\"},\"wordCount\":1012,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-9367-google-ads-data-retention-37-months--n.png\",\"keywords\":[\"Automation\",\"BigQuery\",\"Digital Marketing\",\"Google Ads\"],\"articleSection\":[\"Digital Marketing\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\\\/\",\"name\":\"Google Ads Data Retention: 37 Months of Performance Data and a Resumable Backfill Job | Lukas Wojcik\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-9367-google-ads-data-retention-37-months--n.png\",\"datePublished\":\"2026-08-12T07:20:00+00:00\",\"dateModified\":\"2026-09-24T21:33:30+00:00\",\"description\":\"Archive Google Ads data: calculate retention boundaries, resume historical exports and track losses in a backfill ledger.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-9367-google-ads-data-retention-37-months--n.png\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-9367-google-ads-data-retention-37-months--n.png\",\"width\":1200,\"height\":630,\"caption\":\"Google Ads Data Retention: 37 Months of Performance Data and a Resumable Backfill Job\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-marketing\\\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Google Ads Data Retention: 37 Months of Performance Data and a Resumable Backfill Job\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"Lukas Wojcik\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"Lukas Wojcik\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Google Ads Data Retention: 37 Months of Performance Data and a Resumable Backfill Job | Lukas Wojcik","description":"Archive Google Ads data: calculate retention boundaries, resume historical exports and track losses in a backfill ledger.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/","og_locale":"en_US","og_type":"article","og_title":"Google Ads Data Retention: 37 Months of Performance Data and a Resumable Backfill Job | Lukas Wojcik","og_description":"Archive Google Ads data: calculate retention boundaries, resume historical exports and track losses in a backfill ledger.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/","og_site_name":"Lukas Wojcik - Blog","article_published_time":"2026-08-12T07:20:00+00:00","article_modified_time":"2026-09-24T21:33:30+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-9367-google-ads-data-retention-37-months--n.png","type":"image\/png"}],"author":"Lukas Wojcik","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Lukas Wojcik","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/#article","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/"},"author":{"name":"Lukas Wojcik","@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"headline":"Google Ads Data Retention: 37 Months of Performance Data and a Resumable Backfill Job","datePublished":"2026-08-12T07:20:00+00:00","dateModified":"2026-09-24T21:33:30+00:00","mainEntityOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/"},"wordCount":1012,"commentCount":0,"publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-9367-google-ads-data-retention-37-months--n.png","keywords":["Automation","BigQuery","Digital Marketing","Google Ads"],"articleSection":["Digital Marketing"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/","url":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/","name":"Google Ads Data Retention: 37 Months of Performance Data and a Resumable Backfill Job | Lukas Wojcik","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/#primaryimage"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-9367-google-ads-data-retention-37-months--n.png","datePublished":"2026-08-12T07:20:00+00:00","dateModified":"2026-09-24T21:33:30+00:00","description":"Archive Google Ads data: calculate retention boundaries, resume historical exports and track losses in a backfill ledger.","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/#primaryimage","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-9367-google-ads-data-retention-37-months--n.png","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-9367-google-ads-data-retention-37-months--n.png","width":1200,"height":630,"caption":"Google Ads Data Retention: 37 Months of Performance Data and a Resumable Backfill Job"},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-marketing\/google-ads-data-retention-37-months-of-performance-data-and-a-resumable\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Google Ads Data Retention: 37 Months of Performance Data and a Resumable Backfill Job"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"Lukas Wojcik","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"Lukas Wojcik"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/9367","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=9367"}],"version-history":[{"count":5,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/9367\/revisions"}],"predecessor-version":[{"id":14924,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/9367\/revisions\/14924"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media\/15125"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=9367"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/categories?post=9367"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=9367"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}