InsightClickIQ on OCI and On-Premises

Some analytics data is not allowed to leave the building. Banks, insurers, public bodies and defence suppliers often instrument internal applications whose usage data is as sensitive as the application's own records. For them, a hosted analytics product is a non-starter regardless of its features. InsightClickIQ is built to run where the data is: on Oracle Cloud Infrastructure, on servers you own, or on a network with no outbound route, with the same container image and the same console as every other deployment.

This post covers both homes together, because they differ in fewer places than you might expect, and those places are the useful part.

Four references change

InsightClickIQ on OCI and on-premises: the same container, a Postgres, an S3-compatible or OCI bucket, a vault, and an optional self-hosted ClickHouseOCI and on-premises: same container, two homesThe application does not change. Four references change: the database URL, the store ref, the secret refs, and the model provider.ORACLE CLOUD (OCI)ON-PREMISES / AIR-GAPPEDThe API containerINSIGHT_PLATFORM=ocior =localsame code, same SDKIngest + consolesnippet, mobile SDKs,console, MCPWhat stays identicalRLS on orgmonthly partitionsretention round 03:00QuerySpec enginerules fallbackOCI Database with PostgreSQL2 OCPU to startRLS, partitionsPostgres 16 + PatroniHA by leader electionPgBouncer, transaction modeDBObject Storageoci://namespace/bucketreplays + PDFsMinIO or Cephs3+http://host:9000/bucketsame S3 code pathSTOREOCI Vaultoci-vault://ocid1.vaultsecret…resource principalFile or HashiCorp Vaultfile:///run/secrets/pgvault://… or envKEYSSelf-hosted ClickHouseon Compute or OKE;no managed offer on OCIClickHouse OSS24.8 verified locallyonly at large volumeEVENTSOCI Generative AIINSIGHT_LLM_PROVIDER=ocicompartment id requiredLocal model or nonevLLM or Ollama endpoint,or CLICKIQ_AI=falseMODELDashed: only at the large tier. With CLICKIQ_AI=false every AI surface (insight cards, signals, digest, investigations, playbooks) answers from itsrules path, marked "Rules" in the console. An air-gapped site loses the model's wording, not the numbers or the findings.
OCI and on-premises side by side. The container, the schema, row-level security, partitions, the retention round, the query engine and the rules fallback are identical. What changes is where the database, the bucket, the secrets and the model are, and each of those is one setting.

Everything that varies by environment in InsightClickIQ is a reference in configuration, resolved by the shared platform library. That is why there is no “OCI edition” or “on-prem edition”:

SettingOracle Cloud (OCI)On-premises
Platform buildINSIGHT_PLATFORM=oci (also detected from a resource principal)INSIGHT_PLATFORM=local
DatabaseOCI Database with PostgreSQL; INSIGHT_DATABASE_URLPostgres 16, with Patroni for high availability
Object storeoci://namespace/bucket — Object Storage, resource or instance principals3+http://minio:9000/clickiq — MinIO or Ceph through the S3 code path
Secretsoci-vault://ocid1.vaultsecret…file:///run/secrets/pg, vault://secret/… (HashiCorp KV v2) or env://VAR
ModelOCI Generative AI: INSIGHT_LLM_PROVIDER=oci plus a compartment idAny OpenAI-compatible endpoint (vLLM, Ollama, LM Studio) via INSIGHT_LLM_BASE_URL, or none: CLICKIQ_AI=false
Events at large scaleSelf-managed ClickHouse on Compute or OKEClickHouse OSS (24.8 verified)

On Oracle Cloud

Database and bucket

OCI Database with PostgreSQL runs the schema as it is: row-level security on the organization, the event table in monthly partitions, sessions, people and console content beside it. Start at 2 OCPU for the small tier. Create the application role as an ordinary login (NOSUPERUSER NOBYPASSRLS) so the policies bind it, and give it the role defaults the project ships: statement_timeout = 30s, work_mem = 64MB.

Replay bodies and report PDFs go to Object Storage through an oci:// ref. The store authenticates with a resource principal or instance principal when it runs inside OCI, falling back to ~/.oci/config on a workstation, so there is no key in the container's environment. The Postgres password sits in OCI Vault and is read by its OCID.

The model

With INSIGHT_LLM_PROVIDER=oci the AI features call OCI Generative AI. The provider needs INSIGHT_OCI_COMPARTMENT_ID; the endpoint defaults to the Chicago region and the chat model to cohere.command-r-plus unless you name another. The model plans validated query specifications and writes narratives around results the engine already computed; it never writes SQL and never sees raw events, so which model you choose changes the wording, not the numbers.

No managed ClickHouse

This is the one real gap on OCI. AWS, Azure and Google Cloud all offer ClickHouse Cloud; OCI does not. Below about 100 million events a month that does not matter, because Postgres with partitions carries the event table. Above it, plan to run ClickHouse yourself on Compute or OKE. Autonomous Data Warehouse is the alternative people suggest, and it would need its own dialect in the query engine, which is not built.

Heatmaps · /products/NW-JKT-001
A click heatmap drawn over a rebuilt product page for the Ridgeline Shell Jacket: hot spots on the review stars, size buttons and Add to cart, with a scroll-depth panel showing 79% reach half the page
The page under the heat comes from the object store. It is a rebuilt DOM snapshot taken from a recorded session’s rrweb chunks, not a screenshot — so it reads from Object Storage on OCI or MinIO on-premises. 1,223 clicks over 837 sessions; 79% of visitors reach half the page.

On-premises

The project's compose file is the template for a pilot: Postgres 16 and the API on one machine, with a ClickHouse 24.8 service behind a profile for when you need it. The API image is two-stage: the build stage needs read access to the platform packages, passed as a build secret that never becomes a layer, and the runtime stage has no compiler, no git and runs as an unprivileged user. For an isolated network, build the image where it can reach the package repository, then move it in through your registry.

ConcernOn-premises answer
High availabilityPatroni in front of Postgres 16; the API reconnects through whatever address your HA layer exposes. A connection pooler (PgBouncer) is safe in transaction mode, because the tenant is set per transaction.
Object storeMinIO or Ceph through the same S3 client as AWS, with an s3+http:// or s3+https:// endpoint. Access keys are secret refs (INSIGHT_S3_ACCESS_KEY_REF), not values.
SecretsA mounted file, HashiCorp Vault KV v2, or an environment variable. Rows in the database never hold a secret value, only a ref.
The SDKServed by the API itself at /sdk/clickiq.js from inside the image. Nothing is loaded from a public CDN.
CountryFrom an X-Country header your proxy sets, a MaxMind file mounted as CLICKIQ_GEOIP_DB, or the browser's time zone. No lookup service.
BackupsYour Postgres backup regime, with point-in-time recovery, plus bucket replication only if replays must survive a site loss. Most teams accept re-recording.

When there is no model

The question an air-gapped buyer asks first is whether “AI-native” means “broken without the internet”. It does not, because of how the AI is built. Every number in the product comes from the query engine, not the model. The model has two jobs: choosing which validated queries to run for a question, and putting computed results into words. Both have a rules path.

SurfaceWith a modelWith CLICKIQ_AI=false
Insight strip on every screen (17 surfaces)A narrative, findings and questions worded by the model from computed factsA rules template per surface: ±20% changes flagged up or down, rising errors or rage clicks as risks
SignalsDetected statistically; the model writes the narrative and recommendationDetected the same way; a rule per kind writes them
Weekly digestA headline and paragraph from the real KPI deltas and moversThe same facts composed by rule
InvestigationsMany sessions summarised and clustered into themes with evidenceGrouped by outcome and dominant problem: rage element, error, dead click, exit page
Agent playbooksA tool-using loop chooses its next stepThe playbook's fixed plan runs the same tools; findings read off the results
AskPlans queries from the questionA rule-based planner answers the common questions
Signals · Frustration
The Signals page filtered to frustration: Apply coupon on /cart frustrated 78 sessions with 53 rage clicks and 110 dead clicks, about 6 lost conversions and $1,841 at risk, alongside review-star elements on product pages
Detection never needed the model. 78 sessions, 53 rage clicks, 110 dead clicks, about 6 lost conversions and $1,841 at risk are computed statistically from the event table. In an air-gapped install the same card appears with a rule-written narrative and a “Rules” badge.

A middle path is common: a model on your own hardware behind an OpenAI-compatible API. Set INSIGHT_LLM_PROVIDER=openai and INSIGHT_LLM_BASE_URL at a vLLM or Ollama endpoint inside the network. Smaller local models word things less well; because they only word computed results, they cannot make the numbers wrong, and any answer that fails validation (unknown finding kinds, links to routes that do not exist) is replaced by the rules reading.

WHAT PEOPLE FEARAn AI product that goes blank offline

Chat boxes, summaries and recommendations that depend on a hosted model, leaving empty panels and spinners when it is unreachable.

WHAT HAPPENSThe same screens, worded by rule

Every AI surface returns the same shape from its rules path, badged “Rules”. Charts, signals, impact estimates, journeys, zones and form analysis are computed exactly as before.

Sizing a pilot

1virtual machine for the pilot
~2 GBPostgres for 13 months at demo volume
0outbound connections required
4references that differ from a cloud install

What the security review will check

  • Input values never leave the browser. Form analytics sends lengths, counts and timings; replay masks every input by default; [data-private] text is masked and [data-clickiq-block] elements are excluded entirely.
  • The write key is public by design. It can add events to one project, never read them, and it can be rotated from the project page. Allowed origins restrict which sites may send.
  • Erasure is a single call. DELETE /api/people/{id} removes a person, every id they were seen under, their sessions, events and replay objects.
  • Tenancy is enforced twice. Routes scope every query, and Postgres row-level security binds the application role. On a self-hosted ClickHouse, which has no RLS, the engine refuses to run any statement without an organization predicate, and the tests assert it on every generated statement.
Errors
The Errors page: one rising error group, Uncaught TypeError reading 'days' in /app.js, 870 occurrences across 223 sessions and 223 people since September 27
Errors, grouped and counted on your own database. 870 occurrences of one checkout TypeError across 223 sessions. Stack traces are captured in the browser and stored next to the session, so the replay of a failing checkout is one click away, without sending either to a third party.

What is not here yet

There is no managed ClickHouse on OCI, so the large tier means operating ClickHouse yourself. Daily rollup tables are on the storage roadmap and not shipped; the warehouse export (Parquet or NDJSON to oci://, MinIO or Ceph) has shipped. Server-side PDF rendering needs headless Chromium in the image; without it the console prints reports from the browser.

An air-gapped install loses the model's wording. It keeps every number, every signal, every replay and every finding.

AWS →  ·  Azure →  ·  Google Cloud →  ·  Privacy by design →

← All posts   Request a demo