You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by xi...@apache.org on 2026/03/23 07:03:43 UTC
(pinot-site) 01/01: Restructure homepage: dual workload strip, compressed logos, quickstart CTA, descriptive proof links, SEO alignment
This is an automated email from the ASF dual-hosted git repository.
xiangfu pushed a commit to branch homepage-restructure-dual-workload
in repository https://gitbox.apache.org/repos/asf/pinot-site.git
commit 742c56572bda289bc29f5f882048fff79c692fd1
Author: Xiang Fu <xi...@startree.ai>
AuthorDate: Mon Mar 23 00:03:24 2026 -0700
Restructure homepage: dual workload strip, compressed logos, quickstart CTA, descriptive proof links, SEO alignment
- Add DualWorkloadStrip with paired "Built for User-Facing Apps" and "Built for AI Agents" blocks right after the hero
- Compress logo wall from 66-logo marquee to 10 curated logos in static grid + "See all users" link
- Add QuickstartCTA with copyable Docker command after Features section
- Make all company quote proof links descriptive (e.g. "LinkedIn engineering post" instead of generic "Engineering post")
- Align page title and meta description with hero dual-positioning
Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
---
app/Main.tsx | 4 ++
app/layout.tsx | 4 +-
components/CompanyLogoBar.tsx | 68 +++++++++++++++-------
components/DualWorkloadStrip.tsx | 120 +++++++++++++++++++++++++++++++++++++++
components/Features.tsx | 2 -
components/QuickstartCTA.tsx | 63 ++++++++++++++++++++
data/companyQuotes.ts | 14 ++---
7 files changed, 242 insertions(+), 33 deletions(-)
diff --git a/app/Main.tsx b/app/Main.tsx
index fbd88211..5f86fbc3 100644
--- a/app/Main.tsx
+++ b/app/Main.tsx
@@ -5,6 +5,7 @@ import { CoreContent } from 'pliny/utils/contentlayer';
import { Blog } from '@/.contentlayer/generated';
import siteMetadata from '@/data/siteMetadata';
import HeroSection from '@/components/HeroSection';
+import DualWorkloadStrip from '@/components/DualWorkloadStrip';
import CompanyLogoBar from '@/components/CompanyLogoBar';
import TextMediaSplitSection from '@/components/TextMediaSplitSection';
import SectionContainer from '@/components/SectionContainer';
@@ -13,6 +14,7 @@ import CompanyStories from '@/components/CompanyCarousel';
import BenchmarkSection from '@/components/BenchmarkSection';
import CommunitySection from '@/components/CommunitySection';
import TextCodeSplitSection from '@/components/TextCodeSplitSection';
+import QuickstartCTA from '@/components/QuickstartCTA';
import BlogSection from '@/components/BlogSection';
interface HomeProps {
@@ -23,6 +25,7 @@ const Home: FC<HomeProps> = ({ posts }) => {
return (
<>
<HeroSection />
+ <DualWorkloadStrip />
<CompanyLogoBar />
<TextMediaSplitSection
videoUrl={siteMetadata.video.videoUrl}
@@ -33,6 +36,7 @@ const Home: FC<HomeProps> = ({ posts }) => {
ctaHref={siteMetadata.cta.learnMore}
/>
<Features />
+ <QuickstartCTA />
<CompanyStories />
<BenchmarkSection />
<CommunitySection />
diff --git a/app/layout.tsx b/app/layout.tsx
index e1493522..0a845296 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -16,9 +16,9 @@ const work_sans = Work_Sans({
variable: '--custom-font-work-sans'
});
-const homepageTitle = 'Apache Pinot | Distributed OLAP Database for Real-Time Analytics';
+const homepageTitle = 'Apache Pinot | Real-Time Analytics for Users and AI Agents';
const homepageDescription =
- 'Apache Pinot is an open-source distributed OLAP database delivering sub-second queries on fresh data at 100K+ QPS. Built for user-facing and agent-facing real-time analytics at petabyte scale.';
+ 'Open-source distributed OLAP database for user-facing apps and AI agents. Query fresh streaming data with sub-second latency, high concurrency, and petabyte-scale performance.';
export const metadata: Metadata = {
metadataBase: new URL(siteMetadata.siteUrl),
diff --git a/components/CompanyLogoBar.tsx b/components/CompanyLogoBar.tsx
index 4daa0ba7..d123f406 100644
--- a/components/CompanyLogoBar.tsx
+++ b/components/CompanyLogoBar.tsx
@@ -1,33 +1,57 @@
import Image from 'next/image';
+import Link from 'next/link';
import React from 'react';
import companyLogos from '@/data/companyLogos';
+// Curated top-tier logos for the compressed trust bar (10 logos)
+const featuredLogoNames = [
+ 'LinkedIn',
+ 'Uber',
+ 'Stripe',
+ 'Walmart',
+ 'Visa',
+ 'NVIDIA',
+ 'Goldman Sachs',
+ 'Slack',
+ 'Target',
+ 'DoorDash'
+];
+
+const featuredLogos = featuredLogoNames
+ .map((name) => companyLogos.find((c) => c.name === name))
+ .filter(Boolean) as (typeof companyLogos)[number][];
+
const CompanyLogoBar: React.FC = () => {
return (
- <section className="flex flex-col py-14 md:py-[4rem]">
- <div className="mx-auto w-full">
- <h3 className="mb-12 text-center text-lg font-semibold text-gray-700 dark:text-gray-300 md:text-xl">
+ <section className="flex flex-col py-10 md:py-14">
+ <div className="mx-auto w-full max-w-6xl px-6">
+ <h3 className="mb-8 text-center text-lg font-semibold text-gray-700 dark:text-gray-300 md:text-xl">
Trusted by engineering teams at leading companies
</h3>
- <div className="relative overflow-hidden">
- {/* Fade edges */}
- <div className="pointer-events-none absolute left-0 top-0 z-10 h-full w-24 bg-gradient-to-r from-white dark:from-gray-950" />
- <div className="pointer-events-none absolute right-0 top-0 z-10 h-full w-24 bg-gradient-to-l from-white dark:from-gray-950" />
- <div className="flex w-max animate-marquee items-center gap-12">
- {/* Render logos twice for seamless loop */}
- {[...companyLogos, ...companyLogos].map((company, index) => (
- <div key={index} className="flex shrink-0 items-center justify-center">
- <Image
- src={company.logo}
- alt={company.alt}
- width={240}
- height={80}
- className="h-auto w-auto max-w-[200px] dark:invert md:max-w-[240px]"
- priority={false}
- />
- </div>
- ))}
- </div>
+ <div className="flex flex-wrap items-center justify-center gap-x-10 gap-y-6 md:gap-x-14">
+ {featuredLogos.map((company) => (
+ <div
+ key={company.name}
+ className="flex shrink-0 items-center justify-center"
+ >
+ <Image
+ src={company.logo}
+ alt={company.alt}
+ width={200}
+ height={60}
+ className="h-auto w-auto max-w-[120px] dark:invert md:max-w-[160px]"
+ priority={false}
+ />
+ </div>
+ ))}
+ </div>
+ <div className="mt-6 text-center">
+ <Link
+ href="/powered-by/"
+ className="text-sm font-medium text-gray-600 hover:text-gray-900 hover:underline dark:text-gray-400 dark:hover:text-gray-200"
+ >
+ See all users →
+ </Link>
</div>
</div>
</section>
diff --git a/components/DualWorkloadStrip.tsx b/components/DualWorkloadStrip.tsx
new file mode 100644
index 00000000..b7e3e435
--- /dev/null
+++ b/components/DualWorkloadStrip.tsx
@@ -0,0 +1,120 @@
+import Link from 'next/link';
+
+const userFacingPatterns = [
+ {
+ title: 'Embedded Analytics',
+ description:
+ 'Ship interactive dashboards inside your product — 100K+ concurrent users querying live data with sub-second latency.'
+ },
+ {
+ title: 'Customer Dashboards',
+ description:
+ 'Let customers explore their own data in real time with multitenant isolation, no pre-aggregation required.'
+ },
+ {
+ title: 'Metrics APIs',
+ description:
+ 'Expose low-latency analytics endpoints that power leaderboards, usage meters, and real-time reporting.'
+ }
+];
+
+const agentFacingPatterns = [
+ {
+ title: 'RAG on Fresh Events',
+ description:
+ 'Retrieve real-time context from streaming data so LLMs ground answers in facts, not stale snapshots.'
+ },
+ {
+ title: 'Decision Engines',
+ description:
+ 'Feed live signals — ad bids, fraud scores, pricing — to models that act in milliseconds, not minutes.'
+ },
+ {
+ title: 'Agentic Observability',
+ description:
+ 'Let autonomous agents query system metrics and logs in real time to self-diagnose and self-heal.'
+ }
+];
+
+const DualWorkloadStrip = () => {
+ return (
+ <section className="px-6 py-14 md:mx-auto md:max-w-screen-outerLiveArea md:px-[6.75rem] md:py-[4rem]">
+ <div className="mx-auto max-w-7xl">
+ <h2 className="mb-3 text-center text-[1.75rem] font-semibold md:text-[2rem]">
+ Best for
+ </h2>
+ <p className="mx-auto mb-10 max-w-2xl text-center text-gray-600 dark:text-gray-400">
+ Pinot powers both human-facing products and autonomous AI systems with the same
+ real-time engine.
+ </p>
+ <div className="grid grid-cols-1 gap-6 lg:grid-cols-2">
+ {/* User-Facing Apps */}
+ <div className="rounded-xl border border-blue-200 bg-blue-50 px-6 py-8 dark:border-blue-900 dark:bg-blue-950/30 md:px-8">
+ <h3 className="mb-2 text-lg font-semibold md:text-xl">
+ Built for User-Facing Apps
+ </h3>
+ <p className="mb-5 text-sm text-gray-600 dark:text-gray-400">
+ Serve interactive analytics to millions of end users with sub-second
+ query latency at any scale.
+ </p>
+ <div className="space-y-4">
+ {userFacingPatterns.map((pattern) => (
+ <div
+ key={pattern.title}
+ className="rounded-lg border border-blue-200 bg-white px-5 py-4 dark:border-blue-800 dark:bg-gray-900"
+ >
+ <h4 className="mb-1 font-semibold">{pattern.title}</h4>
+ <p className="text-sm text-gray-600 dark:text-gray-400">
+ {pattern.description}
+ </p>
+ </div>
+ ))}
+ </div>
+ <div className="mt-5 text-center">
+ <Link
+ href="/use-cases/"
+ className="text-sm font-medium text-blue-700 hover:underline dark:text-blue-400"
+ >
+ Explore use cases →
+ </Link>
+ </div>
+ </div>
+
+ {/* Agent-Facing AI */}
+ <div className="rounded-xl border border-amber-200 bg-amber-50 px-6 py-8 dark:border-amber-900 dark:bg-amber-950/30 md:px-8">
+ <h3 className="mb-2 text-lg font-semibold md:text-xl">
+ Built for AI Agents
+ </h3>
+ <p className="mb-5 text-sm text-gray-600 dark:text-gray-400">
+ Sub-second SQL over fresh data makes Pinot a natural backend for
+ LLM-powered systems that reason on live state.
+ </p>
+ <div className="space-y-4">
+ {agentFacingPatterns.map((pattern) => (
+ <div
+ key={pattern.title}
+ className="rounded-lg border border-amber-200 bg-white px-5 py-4 dark:border-amber-800 dark:bg-gray-900"
+ >
+ <h4 className="mb-1 font-semibold">{pattern.title}</h4>
+ <p className="text-sm text-gray-600 dark:text-gray-400">
+ {pattern.description}
+ </p>
+ </div>
+ ))}
+ </div>
+ <div className="mt-5 text-center">
+ <Link
+ href="/agent-facing-analytics/"
+ className="text-sm font-medium text-amber-800 hover:underline dark:text-amber-500"
+ >
+ Learn about agent-facing analytics →
+ </Link>
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+ );
+};
+
+export default DualWorkloadStrip;
diff --git a/components/Features.tsx b/components/Features.tsx
index c1788550..93a54984 100644
--- a/components/Features.tsx
+++ b/components/Features.tsx
@@ -1,5 +1,4 @@
import Feature from './Feature';
-import AgentStrip from './AgentStrip';
import featuresData from '@/data/featuresData';
import pinotMeta from '@/data/pinot-meta.json';
@@ -7,7 +6,6 @@ const Features: React.FC = () => {
return (
<section className="flex px-6 py-14 md:mx-auto md:max-w-screen-outerLiveArea md:px-[6.75rem] md:py-[6.5rem]">
<div className="mx-auto max-w-7xl">
- <AgentStrip />
<h3 className="pb-8 text-center text-[1.75rem] font-semibold md:pb-16 md:text-[2rem]">
Features
</h3>
diff --git a/components/QuickstartCTA.tsx b/components/QuickstartCTA.tsx
new file mode 100644
index 00000000..2a6e00eb
--- /dev/null
+++ b/components/QuickstartCTA.tsx
@@ -0,0 +1,63 @@
+'use client';
+
+import React, { useState } from 'react';
+import Link from 'next/link';
+import siteMetadata from '@/data/siteMetadata';
+
+const dockerCommand =
+ 'docker run -p 9000:9000 apachepinot.docker.scarf.sh/apachepinot/pinot:1.4.0 QuickStart -type hybrid';
+
+const QuickstartCTA: React.FC = () => {
+ const [copied, setCopied] = useState(false);
+
+ const handleCopy = async () => {
+ try {
+ await navigator.clipboard.writeText(dockerCommand);
+ setCopied(true);
+ setTimeout(() => setCopied(false), 2000);
+ } catch (err) {
+ console.error('Failed to copy text: ', err);
+ }
+ };
+
+ return (
+ <section className="px-6 py-10 md:mx-auto md:max-w-screen-outerLiveArea md:px-[6.75rem] md:py-14">
+ <div className="mx-auto max-w-3xl rounded-xl border border-gray-200 bg-gray-50 px-6 py-8 text-center dark:border-gray-700 dark:bg-gray-900 md:px-10">
+ <h3 className="mb-2 text-lg font-semibold md:text-xl">
+ Run Pinot locally in 60 seconds
+ </h3>
+ <div
+ className="group mx-auto mt-4 flex max-w-2xl cursor-pointer items-center justify-between gap-3 rounded-lg border border-gray-300 bg-white px-4 py-3 font-mono text-sm dark:border-gray-600 dark:bg-gray-800"
+ onClick={handleCopy}
+ role="button"
+ tabIndex={0}
+ onKeyDown={(e) => e.key === 'Enter' && handleCopy()}
+ >
+ <code className="truncate text-left text-gray-700 dark:text-gray-300">
+ <span className="select-none text-gray-400">$ </span>
+ {dockerCommand}
+ </code>
+ <span className="shrink-0 text-xs text-gray-400 transition-colors group-hover:text-gray-600 dark:group-hover:text-gray-300">
+ {copied ? 'copied!' : 'copy'}
+ </span>
+ </div>
+ <p className="mt-4 text-sm text-gray-500 dark:text-gray-400">
+ Then open{' '}
+ <code className="rounded bg-gray-200 px-1.5 py-0.5 text-xs dark:bg-gray-700">
+ localhost:9000
+ </code>{' '}
+ to explore the query console.{' '}
+ <Link
+ href={siteMetadata.cta.getStarted}
+ target="_blank"
+ className="font-medium text-vine-100 hover:underline"
+ >
+ Full getting started guide →
+ </Link>
+ </p>
+ </div>
+ </section>
+ );
+};
+
+export default QuickstartCTA;
diff --git a/data/companyQuotes.ts b/data/companyQuotes.ts
index ee6885ea..654bb57f 100644
--- a/data/companyQuotes.ts
+++ b/data/companyQuotes.ts
@@ -21,7 +21,7 @@ const quotes: CompanyQuote[] = [
value: '250K+ QPS',
label: 'across 50+ user-facing applications'
},
- sourceLabel: 'Engineering post',
+ sourceLabel: 'LinkedIn engineering post',
sourceUrl:
'https://engineering.linkedin.com/blog/2021/real-time-analytics-at-scale-with-pinot'
},
@@ -34,7 +34,7 @@ const quotes: CompanyQuote[] = [
value: '200K QPS',
label: 'at P99 latency of 70ms across 3PB'
},
- sourceLabel: 'Case study',
+ sourceLabel: 'Stripe case study',
sourceUrl:
'https://startree.ai/user-stories/stripe-journey-to-18-b-of-transactions-with-apache-pinot'
},
@@ -47,7 +47,7 @@ const quotes: CompanyQuote[] = [
value: '500M+',
label: 'queries served daily via Neutrino'
},
- sourceLabel: 'Engineering post',
+ sourceLabel: 'Uber engineering post',
sourceUrl: 'https://www.uber.com/blog/engineering/real-time-analytics/'
},
{
@@ -59,7 +59,7 @@ const quotes: CompanyQuote[] = [
value: '500 nodes',
label: 'eliminated vs. Elasticsearch'
},
- sourceLabel: 'Case study',
+ sourceLabel: 'Webex case study',
sourceUrl: 'https://pinot.apache.org/powered-by/'
},
{
@@ -71,7 +71,7 @@ const quotes: CompanyQuote[] = [
value: '<100ms',
label: 'latency, down from 30s timeouts'
},
- sourceLabel: 'Engineering post',
+ sourceLabel: 'DoorDash engineering post',
sourceUrl:
'https://doordash.engineering/2024/01/09/from-elasticsearch-to-apache-pinot-at-doordash/'
},
@@ -84,7 +84,7 @@ const quotes: CompanyQuote[] = [
value: '14M',
label: 'events/min ingested with <900ms lag'
},
- sourceLabel: 'Engineering post',
+ sourceLabel: 'Walmart engineering post',
sourceUrl:
'https://medium.com/walmartglobaltech/walmarts-real-time-analytics-with-apache-pinot-a9ecf4d76ee'
},
@@ -97,7 +97,7 @@ const quotes: CompanyQuote[] = [
value: '1M events/sec',
label: 'at peak, 60B transactions/year'
},
- sourceLabel: 'Engineering post',
+ sourceLabel: 'Razorpay engineering post',
sourceUrl:
'https://engineering.razorpay.com/building-real-time-analytics-at-razorpay-with-apache-pinot-b44ad1e2f244'
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org