Skip to content

feat: cache property values#48263

Open
raquelmsmith wants to merge 30 commits intomasterfrom
feat/prop-value-caching
Open

feat: cache property values#48263
raquelmsmith wants to merge 30 commits intomasterfrom
feat/prop-value-caching

Conversation

@raquelmsmith
Copy link
Member

@raquelmsmith raquelmsmith commented Feb 18, 2026

Problem

Previously, property value suggestions (the autocomplete dropdowns in filters) were fetched fresh from ClickHouse on every request. #49001 added PropertyValuesQueryRunner, which caches results in Redis and returns stale data immediately while enqueuing a background ClickHouse refresh. This PR wires up the frontend to handle that "refreshing" signal and re-poll until fresh values arrive.

Changes

This PR does three things:

  1. Makes the frontend poll for new values when refreshing=true
    • This is for initial values and deduped queried values. Claude tells me clickhouse will only return 20 values for person props, so even if someone queries an email prop for search value a and that gets cached, the cache size should still stay relatively small. Debounce is 300ms so we hopefully aren't caching on every keystroke.
    • Grilling claude about the cache cancelling behavior: If I type a in the search, a queryis fired off, and then I type another key so the query is ab before the a query completes, is the a query cancelled?
      • One wrinkle worth knowing: if "a" completed, got refreshing: true, and scheduled a 2s poll — that poll carries newInput="a" in its closure. If the user has already typed "ab" and gotten results, the stale poll would fire after 2s and call loadPropertyValues with newInput="a", potentially briefly overwriting the "ab" results. That's a pre-existing edge case though, not introduced by this PR.
  2. Makes the query runner schema autogenerated (shoulda caught that in feat: property values query runner #49001 tbh)
  3. Registers the query runner (not sure how that wasn't done in feat: property values query runner #49001 🙃 but I guess it still works?)
**Claude change description, which I actually thought was mildly helpful**

API response format (event.py, person.py)

Both /api/projects/:id/events/values/ and /api/person/values/ previously returned a bare JSON array. They now return { "results": [...], "refreshing": true }. refreshing: true means the backend served cached data and has kicked off a background refresh. All existing tests updated for the new shape.

Query runner registration (query_runner.py)

PropertyValuesQuery is registered in get_query_runner() so it participates in the standard async query infrastructure (cache, execution modes, etc.).

Schema (schema-general.ts, schema.py)

PropertyValuesQuery, PropertyValueItem, PropertyValuesQueryResponse, and CachedPropertyValuesQueryResponse are now defined in the TypeScript schema and generated into schema.py, replacing hand-rolled Python models. PropertyValueItem.name is typed as string | number | boolean | null rather than any.

Async dedup fix (execute_async.py)

Fixed a bug where a completed task left a stale mapping in Redis, permanently blocking re-enqueuing for the same cache key. The fix checks query_status.complete before deduplicating and cleans up stale mappings. Added explicit QueryNotFoundError handling for the race where the mapping exists but the status TTL has expired.

Frontend: polling on refreshing (propertyDefinitionsModel.ts)

The model now:

  • Handles the new { results, refreshing } response shape
  • Tracks refreshing, preRefreshValueNames, and searchInput per property key in the Option type
  • Schedules a 2-second poll when refreshing: true, repeating until the backend returns refreshing: false

Frontend: propertyValueLogic.ts (new file)

A scoped kea logic keyed on type/propertyKey that exposes:

  • isRefreshing — whether a background refresh is in progress
  • newValueNames — names of values that appeared after the latest refresh (for future UI callouts)

Frontend: PropertyValue.tsx

  • Uses isRefreshing from propertyValueLogic to show the loading spinner while a background refresh is running, so users see the cached values immediately but know fresh data is on the way
  • Improved the initial suggested values merging: when a background refresh arrives with a different list, already-shown values are never dropped from under the user's cursor

How did you test this code?

I did a lot of manual testing to make sure this actually works. Claude wrote some backend tests as well.

To test (I removed the testing accommodations but leaving this here in case someone wants to manually locally test again - I can push them back up):

  • Pull branch obviously, make sure you have recent events flowing into your local instance (or run demo data), and that you're on team ID 1 (or adjust the command below)
  • Run command to seed some false values in the cache: python manage.py seed_property_values_cache --team-id 1 --key '$browser_language' --type person --event-names '$pageview' --values TEST_1 TEST_2
    • You can reuse this to reset if you want to test repeatedly
    • To test event props, use python manage.py seed_property_values_cache --team-id 1 --key '$browser' --type event --event-names '$pageview' --values TEST_1 TEST_2
  • Create a trend insight, make sure Pageview is the event, and add a prop filter for current URL. See the initial seeded values instantly. See it refreshing (there is a false 5-second query delay! so we can see this working as if there was a slow query! this will not be merged!!!) and new values eventually come in and get appended to the bottom of the list.

Loom:

https://www.loom.com/share/2b64435ba691495480f689ad4bbfe354

👉 Stay up-to-date with PostHog coding conventions for a smoother review.

Publish to changelog?

no

@raquelmsmith raquelmsmith requested review from a team and pauldambra February 18, 2026 05:14
@assign-reviewers-posthog assign-reviewers-posthog bot requested a review from a team February 18, 2026 05:14
@github-actions
Copy link
Contributor

github-actions bot commented Feb 18, 2026

Size Change: +14.8 kB (+0.01%)

Total Size: 106 MB

Filename Size Change
frontend/dist/exporter.js 20.9 MB +5.71 kB (+0.03%)
frontend/dist/render-query.js 20.7 MB +5.71 kB (+0.03%)
frontend/dist/toolbar 7.67 MB +1.67 kB (+0.02%)
frontend/dist/toolbar.js 7.67 MB +1.67 kB (+0.02%)
ℹ️ View Unchanged
Filename Size Change
frontend/dist/1c 160 kB 0 B
frontend/dist/368Hedgehogs 5.98 kB 0 B
frontend/dist/abap 145 B 0 B
frontend/dist/abnf 145 B 0 B
frontend/dist/accesslog 1.04 kB 0 B
frontend/dist/Action 21.1 kB +6 B (+0.03%)
frontend/dist/Actions 1.75 kB 0 B
frontend/dist/actionscript 153 B 0 B
frontend/dist/ada 144 B 0 B
frontend/dist/AdvancedActivityLogsScene 34.5 kB 0 B
frontend/dist/agda 145 B 0 B
frontend/dist/al 143 B 0 B
frontend/dist/angelscript 1.73 kB 0 B
frontend/dist/antlr4 147 B 0 B
frontend/dist/apache 1.05 kB 0 B
frontend/dist/apacheconf 151 B 0 B
frontend/dist/apex 179 B 0 B
frontend/dist/apl 144 B 0 B
frontend/dist/applescript 152 B 0 B
frontend/dist/ApprovalDetail 16.9 kB 0 B
frontend/dist/aql 144 B 0 B
frontend/dist/arcade 2.94 kB 0 B
frontend/dist/arduino 8.88 kB 0 B
frontend/dist/arff 145 B 0 B
frontend/dist/armasm 3.27 kB 0 B
frontend/dist/array.full.es5.js 327 kB 0 B
frontend/dist/array.full.js 426 kB 0 B
frontend/dist/array.js 181 kB 0 B
frontend/dist/asciidoc 149 B 0 B
frontend/dist/asm6502 148 B 0 B
frontend/dist/asmatmel 149 B 0 B
frontend/dist/aspectj 2.69 kB 0 B
frontend/dist/aspnet 181 B 0 B
frontend/dist/AsyncMigrations 13.9 kB 0 B
frontend/dist/AuthorizationStatus 1.43 kB 0 B
frontend/dist/autohotkey 1.04 kB 0 B
frontend/dist/autoit 6.74 kB 0 B
frontend/dist/avisynth 149 B 0 B
frontend/dist/avrasm 2.1 kB 0 B
frontend/dist/avro-idl 149 B 0 B
frontend/dist/awk 804 B 0 B
frontend/dist/axapta 1.76 kB 0 B
frontend/dist/azcli 852 B 0 B
frontend/dist/bash 2.18 kB 0 B
frontend/dist/basic 146 B 0 B
frontend/dist/bat 1.85 kB 0 B
frontend/dist/batch 146 B 0 B
frontend/dist/BatchExportScene 50.6 kB 0 B
frontend/dist/bbcode 147 B 0 B
frontend/dist/bicep 2.56 kB 0 B
frontend/dist/Billing 1.21 kB 0 B
frontend/dist/BillingSection 21.4 kB 0 B
frontend/dist/birb 145 B 0 B
frontend/dist/bison 180 B 0 B
frontend/dist/bnf 144 B 0 B
frontend/dist/brainfuck 150 B 0 B
frontend/dist/brightscript 153 B 0 B
frontend/dist/bro 144 B 0 B
frontend/dist/browserAll-0QZMN1W2 37.3 kB 0 B
frontend/dist/bsl 144 B 0 B
frontend/dist/ButtonPrimitives 1.28 kB 0 B
frontend/dist/c-like 5.27 kB 0 B
frontend/dist/c 142 B 0 B
frontend/dist/cal 1.12 kB 0 B
frontend/dist/CalendarHeatMap 5.53 kB 0 B
frontend/dist/cameligo 2.2 kB 0 B
frontend/dist/capnproto 974 B 0 B
frontend/dist/ceylon 1.24 kB 0 B
frontend/dist/cfscript 149 B 0 B
frontend/dist/chaiscript 219 B 0 B
frontend/dist/changeRequestsLogic 1.26 kB 0 B
frontend/dist/cil 144 B 0 B
frontend/dist/clean 671 B 0 B
frontend/dist/CLIAuthorize 12 kB 0 B
frontend/dist/clike 146 B 0 B
frontend/dist/CLILive 4.71 kB 0 B
frontend/dist/clojure 3.76 kB 0 B
frontend/dist/clojure-repl 326 B 0 B
frontend/dist/cmake 146 B 0 B
frontend/dist/cobol 146 B 0 B
frontend/dist/coffee 3.6 kB 0 B
frontend/dist/coffeescript 153 B 0 B
frontend/dist/Cohort 23.6 kB 0 B
frontend/dist/CohortCalculationHistory 6.95 kB 0 B
frontend/dist/Cohorts 10.1 kB 0 B
frontend/dist/concurnas 150 B 0 B
frontend/dist/ConfirmOrganization 5.21 kB 0 B
frontend/dist/conversations.js 64.5 kB 0 B
frontend/dist/coq 3.61 kB 0 B
frontend/dist/core 315 B 0 B
frontend/dist/cos 1.46 kB 0 B
frontend/dist/Coupons 1.45 kB 0 B
frontend/dist/cpp 5.31 kB 0 B
frontend/dist/Create 1.55 kB 0 B
frontend/dist/crisp-chat-integration.js 2.11 kB 0 B
frontend/dist/crmsh 1.53 kB 0 B
frontend/dist/crystal 182 B 0 B
frontend/dist/csharp 147 B 0 B
frontend/dist/cshtml 181 B 0 B
frontend/dist/csp 571 B 0 B
frontend/dist/css 4.51 kB 0 B
frontend/dist/css-extras 151 B 0 B
frontend/dist/cssMode 4.14 kB 0 B
frontend/dist/csv 144 B 0 B
frontend/dist/CustomCssScene 4.27 kB 0 B
frontend/dist/CustomerAnalyticsConfigurationScene 2.71 kB 0 B
frontend/dist/CustomerAnalyticsScene 31.6 kB 0 B
frontend/dist/customizations.full.js 18.5 kB 0 B
frontend/dist/cypher 3.4 kB 0 B
frontend/dist/d 142 B 0 B
frontend/dist/dart 4.26 kB 0 B
frontend/dist/Dashboard 1.65 kB 0 B
frontend/dist/Dashboards 14 kB 0 B
frontend/dist/DataManagementScene 1.36 kB 0 B
frontend/dist/DataPipelinesNewScene 3 kB 0 B
frontend/dist/DataWarehouseScene 1.37 kB +56 B (+4.27%)
frontend/dist/DataWarehouseSourceScene 1.35 kB 0 B
frontend/dist/dataweave 150 B 0 B
frontend/dist/dax 144 B 0 B
frontend/dist/Deactivated 1.85 kB 0 B
frontend/dist/dead-clicks-autocapture.js 13.1 kB 0 B
frontend/dist/DeadLetterQueue 6.11 kB 0 B
frontend/dist/DebugScene 19.2 kB 0 B
frontend/dist/decompressionWorker 2.85 kB 0 B
frontend/dist/decompressionWorker.js 2.85 kB 0 B
frontend/dist/DefinitionEdit 7.84 kB 0 B
frontend/dist/DefinitionView 23 kB 0 B
frontend/dist/delphi 2.1 kB 0 B
frontend/dist/DestinationsScene 3.4 kB 0 B
frontend/dist/dhall 146 B 0 B
frontend/dist/diff 145 B 0 B
frontend/dist/dist 541 B 0 B
frontend/dist/django 181 B 0 B
frontend/dist/dns 1.88 kB 0 B
frontend/dist/dns-zone-file 154 B 0 B
frontend/dist/docker 147 B 0 B
frontend/dist/dockerfile 1.88 kB 0 B
frontend/dist/dos 1.3 kB 0 B
frontend/dist/dot 144 B 0 B
frontend/dist/dsconfig 724 B 0 B
frontend/dist/dts 1.47 kB 0 B
frontend/dist/dust 585 B 0 B
frontend/dist/EarlyAccessFeature 1.43 kB 0 B
frontend/dist/EarlyAccessFeatures 3.56 kB 0 B
frontend/dist/ebnf 145 B 0 B
frontend/dist/ecl 5.35 kB 0 B
frontend/dist/editorconfig 153 B 0 B
frontend/dist/EditorScene 1.45 kB 0 B
frontend/dist/eiffel 147 B 0 B
frontend/dist/ejs 178 B 0 B
frontend/dist/elixir 10.3 kB 0 B
frontend/dist/elm 144 B 0 B
frontend/dist/EmailMFAVerify 3.7 kB 0 B
frontend/dist/EndpointScene 30.7 kB 0 B
frontend/dist/EndpointsScene 21.8 kB 0 B
frontend/dist/erb 344 B 0 B
frontend/dist/erlang 2.09 kB 0 B
frontend/dist/erlang-repl 1.01 kB 0 B
frontend/dist/ErrorTrackingConfigurationScene 2.76 kB 0 B
frontend/dist/ErrorTrackingIssueFingerprintsScene 6.05 kB 0 B
frontend/dist/ErrorTrackingIssueScene 83.9 kB 0 B
frontend/dist/ErrorTrackingScene 12.1 kB 0 B
frontend/dist/etlua 214 B 0 B
frontend/dist/EvaluationTemplates 1.32 kB 0 B
frontend/dist/EventsScene 3.16 kB 0 B
frontend/dist/excel-formula 154 B 0 B
frontend/dist/excel 4.45 kB 0 B
frontend/dist/exception-autocapture.js 11.9 kB 0 B
frontend/dist/Experiment 283 kB 0 B
frontend/dist/Experiments 17.9 kB 0 B
frontend/dist/exporter 20.9 MB 0 B
frontend/dist/ExportsScene 4.59 kB 0 B
frontend/dist/factor 147 B 0 B
frontend/dist/false 146 B 0 B
frontend/dist/FeatureFlag 105 kB 0 B
frontend/dist/FeatureFlags 1.29 kB 0 B
frontend/dist/FeatureFlagTemplatesScene 4.93 kB 0 B
frontend/dist/firestore-security-rules 165 B 0 B
frontend/dist/fix 529 B 0 B
frontend/dist/FlappyHog 6.51 kB 0 B
frontend/dist/flix 756 B 0 B
frontend/dist/flow 145 B 0 B
frontend/dist/flow9 1.81 kB 0 B
frontend/dist/fortran 148 B 0 B
frontend/dist/freemarker2 16.7 kB 0 B
frontend/dist/fsharp 2.99 kB 0 B
frontend/dist/ftl 178 B 0 B
frontend/dist/gams 3.17 kB 0 B
frontend/dist/gap 144 B 0 B
frontend/dist/gauss 13.1 kB 0 B
frontend/dist/gcode 146 B 0 B
frontend/dist/gdscript 149 B 0 B
frontend/dist/gedcom 147 B 0 B
frontend/dist/gherkin 670 B 0 B
frontend/dist/git 144 B 0 B
frontend/dist/glsl 179 B 0 B
frontend/dist/gml 144 B 0 B
frontend/dist/gn 143 B 0 B
frontend/dist/go 143 B 0 B
frontend/dist/go-module 150 B 0 B
frontend/dist/golo 677 B 0 B
frontend/dist/gradle 1.68 kB 0 B
frontend/dist/graphql 2.27 kB 0 B
frontend/dist/groovy 1.73 kB 0 B
frontend/dist/Group 15 kB 0 B
frontend/dist/Groups 4.65 kB 0 B
frontend/dist/GroupsNew 8.07 kB 0 B
frontend/dist/haml 179 B 0 B
frontend/dist/handlebars 2.51 kB 0 B
frontend/dist/haskell 1.82 kB 0 B
frontend/dist/haxe 2.01 kB 0 B
frontend/dist/hcl 3.6 kB 0 B
frontend/dist/HealthScene 11.7 kB 0 B
frontend/dist/HeatmapNewScene 4.89 kB 0 B
frontend/dist/HeatmapRecordingScene 4.65 kB 0 B
frontend/dist/HeatmapScene 6.7 kB 0 B
frontend/dist/HeatmapsScene 4.6 kB 0 B
frontend/dist/hlsl 179 B 0 B
frontend/dist/HogFunctionScene 59.6 kB 0 B
frontend/dist/HogRepl 8.09 kB 0 B
frontend/dist/hoon 145 B 0 B
frontend/dist/hpkp 145 B 0 B
frontend/dist/hsp 3.51 kB 0 B
frontend/dist/hsts 145 B 0 B
frontend/dist/html 5.56 kB 0 B
frontend/dist/htmlbars 2.62 kB 0 B
frontend/dist/htmlMode 4.6 kB 0 B
frontend/dist/http 1.04 kB 0 B
frontend/dist/hy 3.08 kB 0 B
frontend/dist/ichigojam 150 B 0 B
frontend/dist/icon 145 B 0 B
frontend/dist/icu-message-format 159 B 0 B
frontend/dist/idris 180 B 0 B
frontend/dist/iecst 146 B 0 B
frontend/dist/ignore 147 B 0 B
frontend/dist/image-blob-reduce.esm 49.4 kB 0 B
frontend/dist/InboxScene 22.1 kB 0 B
frontend/dist/index 308 kB 0 B
frontend/dist/index.js 308 kB 0 B
frontend/dist/inform7 802 B 0 B
frontend/dist/ini 1.11 kB 0 B
frontend/dist/InsightOptions 5.48 kB 0 B
frontend/dist/InsightScene 26.1 kB 0 B
frontend/dist/IntegrationsRedirect 1.45 kB 0 B
frontend/dist/intercom-integration.js 2.16 kB 0 B
frontend/dist/InviteSignup 14 kB 0 B
frontend/dist/io 143 B 0 B
frontend/dist/irpf90 4.94 kB 0 B
frontend/dist/isbl 83.8 kB 0 B
frontend/dist/j 142 B 0 B
frontend/dist/java 2.69 kB 0 B
frontend/dist/javadoc 216 B 0 B
frontend/dist/javadoclike 152 B 0 B
frontend/dist/javascript 962 B 0 B
frontend/dist/javastacktrace 155 B 0 B
frontend/dist/jboss-cli 1.02 kB 0 B
frontend/dist/jexl 145 B 0 B
frontend/dist/jolie 146 B 0 B
frontend/dist/jq 143 B 0 B
frontend/dist/js-extras 150 B 0 B
frontend/dist/js-templates 153 B 0 B
frontend/dist/jsdoc 214 B 0 B
frontend/dist/json 714 B 0 B
frontend/dist/json5 180 B 0 B
frontend/dist/jsonMode 13.9 kB 0 B
frontend/dist/jsonp 180 B 0 B
frontend/dist/jsstacktrace 153 B 0 B
frontend/dist/jsx 144 B 0 B
frontend/dist/julia-repl 353 B 0 B
frontend/dist/julia 7.24 kB 0 B
frontend/dist/keepalived 151 B 0 B
frontend/dist/keyman 147 B 0 B
frontend/dist/kotlin 147 B 0 B
frontend/dist/kumir 146 B 0 B
frontend/dist/kusto 146 B 0 B
frontend/dist/lasso 3.07 kB 0 B
frontend/dist/latex 3.68 kB 0 B
frontend/dist/latte 214 B 0 B
frontend/dist/lazy 152 kB 0 B
frontend/dist/ldif 475 B 0 B
frontend/dist/leaf 564 B 0 B
frontend/dist/LegacyPluginScene 21.8 kB 0 B
frontend/dist/LemonDialog 1.2 kB 0 B
frontend/dist/less 7.7 kB 0 B
frontend/dist/lexon 2.45 kB 0 B
frontend/dist/lib 2.23 kB 0 B
frontend/dist/lilypond 183 B 0 B
frontend/dist/LinkScene 25.6 kB 0 B
frontend/dist/LinksScene 4.92 kB 0 B
frontend/dist/liquid 4.51 kB 0 B
frontend/dist/lisp 1.27 kB 0 B
frontend/dist/livecodeserver 8.34 kB 0 B
frontend/dist/LiveDebugger 19.7 kB 0 B
frontend/dist/LiveEventsTable 5.13 kB 0 B
frontend/dist/livescript 3.54 kB 0 B
frontend/dist/LLMAnalyticsClusterScene 16.4 kB 0 B
frontend/dist/LLMAnalyticsClustersScene 38.5 kB 0 B
frontend/dist/LLMAnalyticsDatasetScene 20.4 kB 0 B
frontend/dist/LLMAnalyticsDatasetsScene 4 kB 0 B
frontend/dist/LLMAnalyticsEvaluation 39.6 kB 0 B
frontend/dist/LLMAnalyticsEvaluationsScene 8.16 kB 0 B
frontend/dist/LLMAnalyticsPlaygroundScene 1.3 kB 0 B
frontend/dist/LLMAnalyticsScene 48.9 kB 0 B
frontend/dist/LLMAnalyticsSessionScene 13.5 kB 0 B
frontend/dist/LLMAnalyticsTraceScene 98.2 kB 0 B
frontend/dist/LLMAnalyticsUsers 1.24 kB 0 B
frontend/dist/LLMASessionFeedbackDisplay 5.56 kB 0 B
frontend/dist/LLMPromptScene 13.9 kB 0 B
frontend/dist/LLMPromptsScene 4.02 kB 0 B
frontend/dist/llvm 145 B 0 B
frontend/dist/log 144 B 0 B
frontend/dist/Login 9.09 kB 0 B
frontend/dist/Login2FA 4.93 kB 0 B
frontend/dist/logs.js 39 kB 0 B
frontend/dist/LogsScene 109 kB 0 B
frontend/dist/lolcode 148 B 0 B
frontend/dist/lsl 12 kB 0 B
frontend/dist/lua 2 kB 0 B
frontend/dist/m3 2.82 kB 0 B
frontend/dist/magma 146 B 0 B
frontend/dist/makefile 1.2 kB 0 B
frontend/dist/ManagedMigration 14.8 kB 0 B
frontend/dist/markdown 3.79 kB 0 B
frontend/dist/MarketingAnalyticsScene 24.2 kB 0 B
frontend/dist/markup-templating 158 B 0 B
frontend/dist/markup 147 B 0 B
frontend/dist/MaterializedColumns 10.9 kB 0 B
frontend/dist/mathematica 113 kB 0 B
frontend/dist/matlab 147 B 0 B
frontend/dist/Max 1.41 kB 0 B
frontend/dist/maxima 28.8 kB 0 B
frontend/dist/maxscript 150 B 0 B
frontend/dist/mdx 5.36 kB 0 B
frontend/dist/mel 16.7 kB 0 B
frontend/dist/mercury 2.19 kB 0 B
frontend/dist/mermaid 148 B 0 B
frontend/dist/MessageTemplate 16.9 kB 0 B
frontend/dist/mips 2.59 kB 0 B
frontend/dist/mipsasm 2.58 kB 0 B
frontend/dist/mizar 856 B 0 B
frontend/dist/ModelsScene 2.42 kB 0 B
frontend/dist/mojolicious 443 B 0 B
frontend/dist/mongodb 148 B 0 B
frontend/dist/monkey 1.46 kB 0 B
frontend/dist/moonscript 151 B 0 B
frontend/dist/MoveToPostHogCloud 5.17 kB 0 B
frontend/dist/msdax 4.92 kB 0 B
frontend/dist/mysql 11.3 kB 0 B
frontend/dist/n1ql 3.12 kB 0 B
frontend/dist/n4js 145 B 0 B
frontend/dist/nand2tetris-hdl 156 B 0 B
frontend/dist/naniscript 151 B 0 B
frontend/dist/nasm 145 B 0 B
frontend/dist/neon 145 B 0 B
frontend/dist/nevod 146 B 0 B
frontend/dist/NewSourceWizard 1.44 kB 0 B
frontend/dist/NewTabScene 1.33 kB 0 B
frontend/dist/nginx 1.51 kB 0 B
frontend/dist/nim 144 B 0 B
frontend/dist/nix 770 B 0 B
frontend/dist/node-repl 369 B 0 B
frontend/dist/NotebookCanvasScene 3.68 kB 0 B
frontend/dist/NotebookScene 8.72 kB 0 B
frontend/dist/NotebooksScene 8.24 kB 0 B
frontend/dist/nsis 145 B 0 B
frontend/dist/OAuthAuthorize 10.4 kB 0 B
frontend/dist/objective-c 2.42 kB 0 B
frontend/dist/objectivec 2.67 kB 0 B
frontend/dist/ocaml 146 B 0 B
frontend/dist/Onboarding 642 kB 0 B
frontend/dist/OnboardingCouponRedemption 1.91 kB 0 B
frontend/dist/opencl 181 B 0 B
frontend/dist/openqasm 149 B 0 B
frontend/dist/openscad 1.43 kB 0 B
frontend/dist/oxygene 2.06 kB 0 B
frontend/dist/oz 143 B 0 B
frontend/dist/parigp 147 B 0 B
frontend/dist/parser 147 B 0 B
frontend/dist/parser3 689 B 0 B
frontend/dist/pascal 3 kB 0 B
frontend/dist/pascaligo 150 B 0 B
frontend/dist/passkeyLogic 1.2 kB 0 B
frontend/dist/PasswordReset 5.04 kB 0 B
frontend/dist/PasswordResetComplete 3.65 kB 0 B
frontend/dist/pcaxis 147 B 0 B
frontend/dist/peoplecode 151 B 0 B
frontend/dist/perl 8.26 kB 0 B
frontend/dist/PersonScene 16.4 kB 0 B
frontend/dist/PersonsScene 5.18 kB 0 B
frontend/dist/pf 1.41 kB 0 B
frontend/dist/pgsql 19 kB 0 B
frontend/dist/php 8.03 kB 0 B
frontend/dist/php-extras 219 B 0 B
frontend/dist/php-template 576 B 0 B
frontend/dist/phpdoc 249 B 0 B
frontend/dist/PipelineStatusScene 6.95 kB 0 B
frontend/dist/pla 1.69 kB 0 B
frontend/dist/plaintext 268 B 0 B
frontend/dist/plsql 180 B 0 B
frontend/dist/pony 1.11 kB 0 B
frontend/dist/posthog 252 kB 0 B
frontend/dist/postiats 7.86 kB 0 B
frontend/dist/powerquery 151 B 0 B
frontend/dist/powershell 3.28 kB 0 B
frontend/dist/PreflightCheck 6.27 kB 0 B
frontend/dist/processing 151 B 0 B
frontend/dist/product-tours.js 118 kB 0 B
frontend/dist/ProductTour 481 kB 0 B
frontend/dist/ProductTours 5.43 kB 0 B
frontend/dist/profile 632 B 0 B
frontend/dist/ProjectHomepage 6.54 kB 0 B
frontend/dist/prolog 147 B 0 B
frontend/dist/promql 147 B 0 B
frontend/dist/properties 859 B 0 B
frontend/dist/protobuf 824 B 0 B
frontend/dist/psl 144 B 0 B
frontend/dist/pug 144 B 0 B
frontend/dist/puppet 147 B 0 B
frontend/dist/pure 145 B 0 B
frontend/dist/purebasic 1.74 kB 0 B
frontend/dist/purescript 185 B 0 B
frontend/dist/python 4.75 kB 0 B
frontend/dist/python-repl 375 B 0 B
frontend/dist/q 1.28 kB 0 B
frontend/dist/qml 144 B 0 B
frontend/dist/qore 145 B 0 B
frontend/dist/qsharp 147 B 0 B
frontend/dist/r 3.24 kB 0 B
frontend/dist/racket 181 B 0 B
frontend/dist/razor 9.31 kB 0 B
frontend/dist/reason 147 B 0 B
frontend/dist/reasonml 3.41 kB 0 B
frontend/dist/recorder-v2.js 113 kB 0 B
frontend/dist/recorder.js 113 kB 0 B
frontend/dist/redis 3.56 kB 0 B
frontend/dist/redshift 11.8 kB 0 B
frontend/dist/refractor 17.8 kB 0 B
frontend/dist/regex 146 B 0 B
frontend/dist/RegionMap 135 kB 0 B
frontend/dist/rego 145 B 0 B
frontend/dist/render-query 20.7 MB 0 B
frontend/dist/renpy 146 B 0 B
frontend/dist/ResourceTransfer 9.87 kB 0 B
frontend/dist/rest 145 B 0 B
frontend/dist/restructuredtext 3.91 kB 0 B
frontend/dist/RevenueAnalyticsScene 26.3 kB 0 B
frontend/dist/rib 1.44 kB 0 B
frontend/dist/rip 144 B 0 B
frontend/dist/roboconf 149 B 0 B
frontend/dist/robotframework 155 B 0 B
frontend/dist/routeros 2.66 kB 0 B
frontend/dist/rsl 1.2 kB 0 B
frontend/dist/ruby 8.51 kB 0 B
frontend/dist/ruleslanguage 3.98 kB 0 B
frontend/dist/rust 4.17 kB 0 B
frontend/dist/sas 144 B 0 B
frontend/dist/sass 145 B 0 B
frontend/dist/SavedInsights 1.38 kB 0 B
frontend/dist/sb 1.83 kB 0 B
frontend/dist/scala 1.68 kB 0 B
frontend/dist/scheme 147 B 0 B
frontend/dist/scilab 1.33 kB 0 B
frontend/dist/scss 145 B 0 B
frontend/dist/SdkDoctorScene 4.76 kB 0 B
frontend/dist/SessionAttributionExplorerScene 7.29 kB 0 B
frontend/dist/SessionGroupSummariesTable 5.35 kB 0 B
frontend/dist/SessionGroupSummaryScene 17.8 kB 0 B
frontend/dist/SessionProfileScene 16.6 kB 0 B
frontend/dist/SessionRecordingDetail 2.45 kB 0 B
frontend/dist/SessionRecordingFilePlaybackScene 5.19 kB 0 B
frontend/dist/SessionRecordings 1.49 kB 0 B
frontend/dist/SessionRecordingsKiosk 9.58 kB 0 B
frontend/dist/SessionRecordingsPlaylistScene 4.86 kB 0 B
frontend/dist/SessionRecordingsSettingsScene 2.65 kB 0 B
frontend/dist/SessionsScene 4.59 kB 0 B
frontend/dist/SettingsScene 3.71 kB 0 B
frontend/dist/SharedMetric 16 kB 0 B
frontend/dist/SharedMetrics 1.23 kB 0 B
frontend/dist/shell-session 188 B 0 B
frontend/dist/shell 3.08 kB 0 B
frontend/dist/SignalsDebug 28.8 kB 0 B
frontend/dist/SignupContainer 23.6 kB 0 B
frontend/dist/Site 1.91 kB 0 B
frontend/dist/smali 1.23 kB 0 B
frontend/dist/smalltalk 150 B 0 B
frontend/dist/smarty 181 B 0 B
frontend/dist/sml 1.27 kB 0 B
frontend/dist/solidity 149 B 0 B
frontend/dist/solution-file 154 B 0 B
frontend/dist/sophia 2.77 kB 0 B
frontend/dist/SourcesScene 3.87 kB 0 B
frontend/dist/sourceWizardLogic 1.38 kB 0 B
frontend/dist/soy 178 B 0 B
frontend/dist/sparql 181 B 0 B
frontend/dist/splunk-spl 151 B 0 B
frontend/dist/sqf 32.3 kB 0 B
frontend/dist/sql_more 12.4 kB 0 B
frontend/dist/sql 6.73 kB 0 B
frontend/dist/SqlVariableEditScene 7.97 kB 0 B
frontend/dist/squirrel 149 B 0 B
frontend/dist/st 7.41 kB 0 B
frontend/dist/stan 145 B 0 B
frontend/dist/StartupProgram 21.9 kB 0 B
frontend/dist/stata 16.8 kB 0 B
frontend/dist/step21 753 B 0 B
frontend/dist/stylus 147 B 0 B
frontend/dist/subunit 642 B 0 B
frontend/dist/SupportSettingsScene 26.2 kB 0 B
frontend/dist/SupportTicketScene 20 kB 0 B
frontend/dist/SupportTicketsScene 7.3 kB 0 B
frontend/dist/Survey 1.46 kB 0 B
frontend/dist/SurveyFormBuilder 2.26 kB 0 B
frontend/dist/Surveys 14.3 kB 0 B
frontend/dist/surveys.js 90.1 kB 0 B
frontend/dist/SurveyTemplates 1.28 kB 0 B
frontend/dist/SurveyWizard 174 kB 0 B
frontend/dist/swift 7.62 kB 0 B
frontend/dist/systemd 148 B 0 B
frontend/dist/SystemStatus 17.7 kB 0 B
frontend/dist/systemverilog 7.62 kB 0 B
frontend/dist/t4-cs 214 B 0 B
frontend/dist/t4-templating 154 B 0 B
frontend/dist/t4-vb 248 B 0 B
frontend/dist/taggerscript 535 B 0 B
frontend/dist/tap 533 B 0 B
frontend/dist/TaskDetailScene 20.9 kB 0 B
frontend/dist/TaskTracker 17.1 kB 0 B
frontend/dist/tcl 3.57 kB 0 B
frontend/dist/textile 148 B 0 B
frontend/dist/thrift 744 B 0 B
frontend/dist/toml 145 B 0 B
frontend/dist/ToolbarLaunch 3.24 kB 0 B
frontend/dist/tp 1.6 kB 0 B
frontend/dist/tracing-headers.js 1.93 kB 0 B
frontend/dist/TransformationsScene 2.64 kB 0 B
frontend/dist/tremor 147 B 0 B
frontend/dist/tsMode 24 kB 0 B
frontend/dist/tsx 212 B 0 B
frontend/dist/tt2 178 B 0 B
frontend/dist/turtle 147 B 0 B
frontend/dist/twig 1.3 kB 0 B
frontend/dist/TwoFactorReset 4.71 kB 0 B
frontend/dist/typescript 151 B 0 B
frontend/dist/typespec 2.83 kB 0 B
frontend/dist/typoscript 151 B 0 B
frontend/dist/unrealscript 153 B 0 B
frontend/dist/Unsubscribe 2.34 kB 0 B
frontend/dist/uorazor 148 B 0 B
frontend/dist/uri 144 B 0 B
frontend/dist/UserInterview 5.25 kB 0 B
frontend/dist/UserInterviews 2.74 kB 0 B
frontend/dist/v 142 B 0 B
frontend/dist/vala 145 B 0 B
frontend/dist/vb 5.8 kB 0 B
frontend/dist/vbnet 180 B 0 B
frontend/dist/vbscript 1.83 kB 0 B
frontend/dist/vbscript-html 308 B 0 B
frontend/dist/velocity 149 B 0 B
frontend/dist/VercelLinkError 2.63 kB 0 B
frontend/dist/VerifyEmail 5.2 kB 0 B
frontend/dist/verilog 148 B 0 B
frontend/dist/vhdl 1.81 kB 0 B
frontend/dist/vim 144 B 0 B
frontend/dist/visual-basic 153 B 0 B
frontend/dist/warpscript 151 B 0 B
frontend/dist/wasm 145 B 0 B
frontend/dist/web-idl 148 B 0 B
frontend/dist/web-vitals.js 6.6 kB 0 B
frontend/dist/WebAnalyticsScene 6.08 kB 0 B
frontend/dist/WebGLRenderer-DYjOwNoG 60.3 kB 0 B
frontend/dist/WebGPURenderer-B_wkl_Ja 36.2 kB 0 B
frontend/dist/WebScriptsScene 3.26 kB 0 B
frontend/dist/webworkerAll-puPV1rBA 296 B 0 B
frontend/dist/wgsl 7.35 kB 0 B
frontend/dist/wiki 145 B 0 B
frontend/dist/Wizard 5.18 kB 0 B
frontend/dist/wolfram 148 B 0 B
frontend/dist/WorkflowScene 89.5 kB 0 B
frontend/dist/WorkflowsScene 46.4 kB 0 B
frontend/dist/WorldMap 5.4 kB 0 B
frontend/dist/wren 145 B 0 B
frontend/dist/x86asm 19.2 kB 0 B
frontend/dist/xeora 146 B 0 B
frontend/dist/xl 1.77 kB 0 B
frontend/dist/xml-doc 148 B 0 B
frontend/dist/xml 2.14 kB 0 B
frontend/dist/xojo 145 B 0 B
frontend/dist/xquery 147 B 0 B
frontend/dist/yaml 145 B 0 B
frontend/dist/yang 145 B 0 B
frontend/dist/zephir 1.71 kB 0 B
frontend/dist/zig 144 B 0 B

compressed-size-action

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

22 files reviewed, 10 comments

Edit Code Review Agent Settings | Greptile

Comment on lines 117 to 118
# TEST DELAY: Emulate slow query for testing purposes
time.sleep(5)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

time.sleep(5) must be removed before merge

The PR description notes this is a test-only delay, but it's still present in the code that will run in production. This time.sleep(5) blocks the Celery worker for 5 seconds on every event property value refresh. There's a second instance at line 170 for person properties. Both need to be removed.

Suggested change
# TEST DELAY: Emulate slow query for testing purposes
time.sleep(5)
Prompt To Fix With AI
This is a comment left during a code review.
Path: posthog/tasks/property_value_cache.py
Line: 117-118

Comment:
**`time.sleep(5)` must be removed before merge**

The PR description notes this is a test-only delay, but it's still present in the code that will run in production. This `time.sleep(5)` blocks the Celery worker for 5 seconds on every event property value refresh. There's a second instance at line 170 for person properties. Both need to be removed.

```suggestion
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines 169 to 170
# TEST DELAY: Emulate slow query for testing purposes
time.sleep(5)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

time.sleep(5) must be removed before merge

Second instance of the test-only delay. This blocks the Celery worker on every person property value refresh.

Suggested change
# TEST DELAY: Emulate slow query for testing purposes
time.sleep(5)
Prompt To Fix With AI
This is a comment left during a code review.
Path: posthog/tasks/property_value_cache.py
Line: 169-170

Comment:
**`time.sleep(5)` must be removed before merge**

Second instance of the test-only delay. This blocks the Celery worker on every person property value refresh.

```suggestion
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines 122 to 135

# Used for testing this PR only, should be removed
def clear_refresh_cooldown(
team_id: int,
property_type: str,
property_key: str,
search_value: Optional[str] = None,
event_names: Optional[list[str]] = None,
) -> bool:
"""Delete the refresh cooldown key. Returns True if the key existed."""
redis_client = get_client()
cooldown_key = _make_cache_key(team_id, property_type, property_key, search_value, event_names) + ":refreshing"
return redis_client.delete(cooldown_key) > 0

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test-only function should be removed

The comment on line 123 says this is "for testing this PR only, should be removed." clear_refresh_cooldown is only used in the seed_property_value_cache management command (also a test-only artifact). If the management commands are meant to be removed before merge (as stated in the PR description), this function should be removed too.

Suggested change
# Used for testing this PR only, should be removed
def clear_refresh_cooldown(
team_id: int,
property_type: str,
property_key: str,
search_value: Optional[str] = None,
event_names: Optional[list[str]] = None,
) -> bool:
"""Delete the refresh cooldown key. Returns True if the key existed."""
redis_client = get_client()
cooldown_key = _make_cache_key(team_id, property_type, property_key, search_value, event_names) + ":refreshing"
return redis_client.delete(cooldown_key) > 0
Prompt To Fix With AI
This is a comment left during a code review.
Path: posthog/api/property_value_cache.py
Line: 122-135

Comment:
**Test-only function should be removed**

The comment on line 123 says this is "for testing this PR only, should be removed." `clear_refresh_cooldown` is only used in the `seed_property_value_cache` management command (also a test-only artifact). If the management commands are meant to be removed before merge (as stated in the PR description), this function should be removed too.

```suggestion
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines 1 to 2
import json
import time
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused imports should be cleaned up after removing time.sleep

After removing the time.sleep(5) calls, the import time statement will be unused and should be removed.

Prompt To Fix With AI
This is a comment left during a code review.
Path: posthog/tasks/property_value_cache.py
Line: 1-2

Comment:
**Unused imports should be cleaned up after removing `time.sleep`**

After removing the `time.sleep(5)` calls, the `import time` statement will be unused and should be removed.

How can I resolve this? If you propose a fix, please make it concise.

@tests-posthog
Copy link
Contributor

tests-posthog bot commented Feb 18, 2026

Query snapshots: Backend query snapshots updated

Changes: 1 snapshots (1 modified, 0 added, 0 deleted)

What this means:

  • Query snapshots have been automatically updated to match current output
  • These changes reflect modifications to database queries or schema

Next steps:

  • Review the query changes to ensure they're intentional
  • If unexpected, investigate what caused the query to change

Review snapshot changes →

Copy link
Contributor

@aspicer aspicer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, a couple minor fixes. Let's see if this makes it feel better!

breakpoint()
actions.setOptions(propertyKey, propValues, type !== PropertyDefinitionType.FlagValue)

const propValues = Array.isArray(responseData) ? responseData : responseData.results
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing this Array.isArray check has the potentially to quickly become difficult to maintain if we implement more interface differenes between these diffrent values endpoints.

It would be better to just update the endpoints to all return an object (with refreshing: false for the ones that don't support it)

See here:
https://github.com/PostHog/posthog/pull/48656/changes

event_names=event_names,
)

clear_task_running(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to catch errors and make sure that we call this there is a query execution error? Otherwise I think the spinner will keep running?

@andyzzhao
Copy link
Contributor

andyzzhao commented Feb 23, 2026

I realized we already have a mechanism for running an async query upon a stale cache result.

https://github.com/PostHog/posthog/blob/b97e8fd80559a8d2276e34ca01d0bbbd7fa7a625/posthog/hogql_queries/query_runner.py#L1078C1-L1086

So an alternative approach to get the same behavior as this PR would be implementing a PropertyValuesQueryRunner instead of calling execute_hogql_query directly

@raquelmsmith
Copy link
Member Author

Oh shoot I was just about to get this merged in. @andyzzhao do you think the query runner is the better solution and I should do that instead?

@andyzzhao
Copy link
Contributor

@raquelmsmith creating a query runner should be a smaller change and easier to maintain, but up to you!

@raquelmsmith
Copy link
Member Author

okay @andyzzhao I did that here: #49001

I'm not sure if any parts of this PR are still needed after that one but I imagine so - the re-polling from the frontend for the fresh values at least.

raquelmsmith and others added 3 commits February 25, 2026 15:29
- Remove property_value_cache.py, tasks/property_value_cache.py and management commands
- Use PropertyValuesQueryRunner with RECENT_CACHE_CALCULATE_ASYNC_IF_STALE_AND_BLOCKING_ON_MISS
- Return {results, refreshing} from both event and person property values endpoints
- Add 5-sec test delays to _calculate_event and _calculate_person for frontend polling testing
- Update task registration and snapshot to reflect removed tasks
- Remove test_property_value_cache.py (tests now obsolete)
- propertyValueLogic.ts and frontend polling already in place from earlier commits

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@tests-posthog
Copy link
Contributor

tests-posthog bot commented Feb 26, 2026

Visual regression: Storybook UI snapshots updated

Changes: 3 snapshots (3 modified, 0 added, 0 deleted)

What this means:

  • Snapshots have been automatically updated to match current rendering
  • Next CI run will switch to CHECK mode to verify stability
  • If snapshots change again, CHECK mode will fail (indicates flapping)

Next steps:

  • Review the changes to ensure they're intentional
  • Approve if changes match your expectations
  • If unexpected, investigate component rendering

Review snapshot changes →

Comment on lines +299 to +312
if not query_status.complete:
# Only deduplicate against a query that is still in progress
posthoganalytics.capture(
"query duplicate found",
distinct_id=user_id,
properties={
"cache_key": cache_key,
"query_id": existing_query_id,
"query_json": query_json,
},
)
return query_status
# The previous task finished (or failed) — clean up the stale mapping and enqueue a new one
manager.unregister_cache_key_mapping(cache_key)
Copy link
Member Author

@raquelmsmith raquelmsmith Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dedup check here was changed to only short-circuit when the found query is still in-progress (not query_status.complete). Previously it returned any existing mapping unconditionally — including stale complete=True ones left over when a task failed before calling unregister_cache_key_mapping (which only runs when query_status.results is set). That meant one failed task would permanently block re-enqueueing for that cache key until the 20-min TTL expired. Now a completed mapping is cleaned up and a fresh task is enqueued instead.

@tests-posthog
Copy link
Contributor

tests-posthog bot commented Feb 26, 2026

Visual regression: Storybook UI snapshots updated

Changes: 4 snapshots (4 modified, 0 added, 0 deleted)

What this means:

  • Snapshots have been automatically updated to match current rendering
  • Next CI run will switch to CHECK mode to verify stability
  • If snapshots change again, CHECK mode will fail (indicates flapping)

Next steps:

  • Review the changes to ensure they're intentional
  • Approve if changes match your expectations
  • If unexpected, investigate component rendering

Review snapshot changes →

@raquelmsmith
Copy link
Member Author

@greptileai

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 27, 2026

Additional Comments (3)

posthog/api/event.py, line 597
search value not escaped for ILIKE wildcards

PropertyValuesQueryRunner._event_query escapes \, %, and _ in the search value (line 119 of property_values_query_runner.py), but this code path doesn't. A search for test_value would match test_value in the cached path but test[any char]value here.


posthog/api/event.py, line 551
date_to not converted to team timezone

PropertyValuesQueryRunner._event_query uses .astimezone(self.team.timezone_info) before formatting (line 87 of property_values_query_runner.py). This code path omits the conversion, causing inconsistent date ranges for teams in non-UTC timezones.


posthog/queries/property_values.py, line 92
search value not escaped for SQL wildcards

PropertyValuesQueryRunner._event_query escapes \, %, and _ (line 119 of property_values_query_runner.py). This raw SQL path doesn't, so test_value matches test[any char]value instead of the literal string.

@tests-posthog
Copy link
Contributor

tests-posthog bot commented Feb 27, 2026

Visual regression: Storybook UI snapshots updated

Changes: 1 snapshots (1 modified, 0 added, 0 deleted)

What this means:

  • Snapshots have been automatically updated to match current rendering
  • Next CI run will switch to CHECK mode to verify stability
  • If snapshots change again, CHECK mode will fail (indicates flapping)

Next steps:

  • Review the changes to ensure they're intentional
  • Approve if changes match your expectations
  • If unexpected, investigate component rendering

Review snapshot changes →

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants