惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
小众软件
小众软件
Apple Machine Learning Research
Apple Machine Learning Research
Webroot Blog
Webroot Blog
T
The Blog of Author Tim Ferriss
S
Schneier on Security
罗磊的独立博客
P
Privacy & Cybersecurity Law Blog
阮一峰的网络日志
阮一峰的网络日志
F
Fortinet All Blogs
P
Palo Alto Networks Blog
月光博客
月光博客
MongoDB | Blog
MongoDB | Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Simon Willison's Weblog
Simon Willison's Weblog
量子位
NISL@THU
NISL@THU
C
CERT Recently Published Vulnerability Notes
Cisco Talos Blog
Cisco Talos Blog
Stack Overflow Blog
Stack Overflow Blog
Recorded Future
Recorded Future
K
Kaspersky official blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Hacker News - Newest:
Hacker News - Newest: "LLM"
L
Lohrmann on Cybersecurity
酷 壳 – CoolShell
酷 壳 – CoolShell
GbyAI
GbyAI
L
LINUX DO - 热门话题
Help Net Security
Help Net Security
B
Blog RSS Feed
www.infosecurity-magazine.com
www.infosecurity-magazine.com
I
InfoQ
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The Cloudflare Blog
H
Heimdal Security Blog
Last Week in AI
Last Week in AI
美团技术团队
云风的 BLOG
云风的 BLOG
C
Check Point Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
W
WeLiveSecurity
V
Visual Studio Blog
G
GRAHAM CLULEY
AI
AI
Security Latest
Security Latest
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
雷峰网
雷峰网
Cyberwarzone
Cyberwarzone
Microsoft Security Blog
Microsoft Security Blog
P
Proofpoint News Feed

Vercel News

Vercel Open Source Program: Winter 2026 cohort How Notion Workers run untrusted code at scale with Vercel Sandbox How we run Vercel's CDN in front of Discourse From idea to secure checkout in minutes with Stripe Building Slack agents can be easy Scaling redirects to infinity on Vercel Advancing Python typing Gamma builds design-first agents with Vercel How Avalara turns pipe dreams into patent-pending with v0 Keeping community human while scaling with agents How OpenEvidence built a healthcare AI that physicians actually trust Security boundaries in agentic architectures Skills Night: 69,000+ ways agents are getting smarter Video Generation with AI Gateway We Ralph Wiggumed WebStreams to make them 10x faster How Stably ships AI testing agents in hours, not weeks How we built AEO tracking for coding agents Anyone can build agents, but it takes a platform to run them Introducing Geist Pixel The Vercel AI Accelerator is back with $6m in credits Making agent-friendly pages with content negotiation The Vercel OSS Bug Bounty program is now available Introducing the new v0 Run untrusted code with Vercel Sandbox, now generally available How Stripe built a game-changing app in a single flight with v0 How Sensay went from zero to product in six weeks AGENTS.md outperforms skills in our agent evals Agent skills explained: An FAQ Testing if "bash is all you need" AWS databases are now live on the Vercel Marketplace and v0 Use Perplexity Web Search with Vercel AI Gateway Introducing: React Best Practices Nick Bogaty joins Vercel as Chief Revenue Officer How Mux shipped durable video workflows with their @mux/ai SDK How to build agents with filesystems and bash How we made v0 an effective coding agent Stopping the slow death of internal tools Building AI-Generated Pixel Trading Cards with Vercel AI Gateway We removed 80% of our agent’s tools AI SDK 6 Our $1 million hacker challenge for React2Shell Cline now runs on Vercel AI Gateway How to prompt v0 Build smarter workflows with Notion and v0 Vercel launches partner certification Inside Workflow DevKit: How framework integrations work React2Shell Security Bulletin | Vercel Knowledge Base Billions of requests: Black Friday-Cyber Monday 2025 Investing in the Python ecosystem AWS Databases coming to the Vercel Marketplace How we built the v0 iOS app Workflow Builder: Build your own workflow automation platform Vercel Open Source Program: Fall 2025 cohort Self-driving infrastructure Vercel collaborates with Google for Gemini 3 Pro Preview launch Vercel: The anti-vendor-lock-in cloud How Nous Research used BotID to block automated abuse at scale How AI Gateway runs on Fluid compute What we learned building agents at Vercel Build and deploy data applications on Snowflake with v0 BotID Deep Analysis catches a sophisticated bot network in real-time Vercel achieves TISAX AL2 compliance to serve automotive partners Bun runtime on Vercel Functions David Totten Joins Vercel to Lead Global Field Engineering Vercel Ship AI 2025 recap You can just ship agents AI agents and services on the Vercel Marketplace Built-in durability: Introducing Workflow Development Kit Zero-config backends on Vercel AI Cloud Introducing Vercel Agent: Your new Vercel teammate Update regarding Vercel service disruption on October 20, 2025 Agents at work, a partnership with Salesforce and Slack Running Next.js in ChatGPT: How to Build ChatGPT Apps Talha Tariq joins Vercel as CTO of Security Just another (Black) Friday Server rendering benchmarks: Fluid Compute and Cloudflare Workers Towards the AI Cloud: Our Series F Collaborating with Anthropic on Claude Sonnet 4.5 to power intelligent coding agents Preventing the stampede: Request collapsing in the Vercel CDN BotID uncovers hidden SEO poisoning How we made global routing faster with Bloom filters What you need to know about vibe coding Scale to one: How Fluid solves cold starts Addressing security & quality issues with MCP tools - Vercel AI agents at scale: Rox’s Vercel-powered revenue operating system Agentic Infrastructure Zero Data Retention on AI Gateway Optimizing Vercel Sandbox snapshots How Waldium made a blog platform work for humans and AI alike How FLORA shipped a creative agent on Vercel's AI stack Agent responsibly Making Turborepo 96% faster with agents, sandboxes, and humans Unified reporting for all AI Gateway usage new.website joins forces with v0 SERHANT.'s playbook for rapid AI iteration Two startups at global scale without DevOps Chat SDK brings agents to your users 360 billion tokens, 3 million customers, 6 engineers Meet the 2026 Vercel AI Accelerator Cohort Build knowledge agents without embeddings
Building the Black Friday-Cyber Monday live dashboard - Vercel – Vercel
Nanda Syahrasyad · 2024-12-24 · via Vercel News

4 min read

This year, we built a Black Friday-Cyber Monday (BFCM) dashboard to celebrate the success of our customers through the busy retail weekend. The dashboard gave a real-time look inside Vercel's infrastructure, showing live metrics for deployments, requests, blocked traffic, and more.

Building a data-heavy, real-time dashboard with a good user experience comes with challenges. Let's walk through how we overcame them.

Link to headingDashboard architecture

The BFCM dashboard is a Next.js application built using a modified polling architecture. The core of the site works by having the client poll the server for data every 10 seconds.

Upon receiving the request, the server queries our internal database and returns the aggregate metrics to the client. Behind the scenes, our APIs and services stream data about our requests, deployments, and the Vercel Firewall into the database.

Link to headingBackend optimizations

The metrics we wanted to highlight involved scanning terabytes of data. We needed to avoid costly long-running queries and a poor user experience while retrieving data.

Link to headingCost-efficiency: Handling expensive queries with a Vercel Marketplace Integration

We started with this initial query for getting the total requests count:

SELECT count() FROM requests WHERE timestamp > '2024-11-29 00:00:00'

Initial SQL Query

Issues with this query became clear quickly. As more requests came in, the query took longer to run.

To minimize the amount of data to scan, we used a rolling window. Rather than querying from the beginning of Black Friday every time, we queried a smaller five-minute time period instead:

SELECT count() FROM requests WHERE timestamp > now() - INTERVAL 5 MINUTE

Updated SQL query with rolling window

This way, the query only needed to count the records from the last five minutes, resulting in cheaper and faster results. However, it also meant that we didn’t have the total count—the actual data we wanted to display.

To fix this, we used the Upstash KV integration on the Vercel Marketplace. We stored the cumulative count and had the server combine the two numbers into the total.

Link to headingSpeed: Using Incremental Static Regeneration (ISR)

All visitors to the BFCM dashboard saw the exact same data. Instead of calling the database for each visitor to the site, we could fetch data once and cache the response.

To keep data fresh, we invalidated the cache every five seconds. This also meant we only hit our database once in this time period.

To implement this, we used Next.js's built-in time-based Incremental Static Regeneration (ISR) by adding the following two lines of code to our page.tsx file:

page.tsx

// Tell Next.js to render the page as a static page, despite having fetch calls

export const dynamic = 'force-static';

// Invalidate the cache after 5 seconds

export const revalidate = 5;

export default function Page() { ... }

Rendering the page as a static page and setting time based revalidation

  • If the page was fresh (newer than five seconds): We returned the cached page

  • If the page was stale (older than five seconds): We returned the cached page and regenerated a fresh version of the page in the background. The next time a visitor viewed the site, we returned the fresh page

With those optimizations, our backend architecture was complete.

Link to headingFrontend optimizations

Our biggest frontend challenge was delivering a smooth real-time experience. Since the page polls every 10 seconds for new data, the numbers are only updated once in that time frame. This created a clunky jump in numbers when new data came in.

Initial counting animationInitial counting animation

Initial counting animation

Link to headingUser experience: Dynamic visuals with rate of change

We wanted users to have dynamic visuals—simulating the feeling of the number constantly going up. We can achieve this by calculating the rate at which the metrics change over time.

In the backend, we calculated the rate without any infrastructure changes, since we already stored the previous count in a KV store:

export function getRateOfChange() {

const lastCount = getCountFromKv();

const newCount = fetchLatestCount(); // only from last 5 minutes

const rateOfChange = newCount / (Date.now() - lastCount.timestamp)

return rateOfChange;

}

Then, we passed this rate and value to a client component and used requestAnimationFrame to increment the number in the frontend:

counter.tsx

'use client';

import { useEffect, useRef } from 'react';

export function Counter({ value, rateOfChange }) {

const ref = useRef(null);

useEffect(() => {

let id;

const increment = (ts) => {

if (!ref.current) return;

ref.current.textContent = value + rateOfChange * ts;

id = requestAnimationFrame(increment);

};

id = requestAnimationFrame(increment);

return () => {

cancelAnimationFrame(id);

};

}, [rateOfChange]);

return <span ref={ref}>{value}</span>;

}

Link to headingAccuracy: Preventing over/undercounting

While incrementing the count in the frontend provides a smooth visual effect, it can lead to discrepancies between the displayed count and the actual count from the backend.

For accuracy, we dynamically adjusted the rate of change by calculating the difference between the value displayed and the new updated value. This way, if we overcounted, we slowed down the update rate. If we undercounted, we sped it up. To do this we:

  • Tracked the previous rate and value

  • Calculated the difference between the old value and the new value

  • Adjusted the rate of change based on the difference to fine-tune animation speed

  • Updated the previous ref for the next calculation

  • Updated the current ref with the new value

counter.tsx

'use client';

import { useEffect, useRef, useState } from 'react';

export function Counter({ value, rateOfChange }) {

const [rate, setRate] = useState(rateOfChange);

const lastMetric = useRef({

value,

timestamp: null,

});

useEffect(() => {

const percentageDiff = lastMetric.current.value / value;

setRate(rateOfChange * percentageDiff);

}, [value, rateOfChange]);

const ref = useRef(null);

useEffect(() => {

let id;

const increment = (ts) => {

if (!ref.current) return;

const { timestamp, value } = lastMetric.current;

lastMetric.current.timestamp = ts;

const lastTime = timestamp ?? ts;

const diff = (ts - lastTime) * rate;

const newValue = value + diff;

lastMetric.current.value = newValue;

ref.current.textContent = newValue;

id = requestAnimationFrame(increment);

};

id = requestAnimationFrame(increment);

return () => {

cancelAnimationFrame(id);

};

}, [rate]);

return <span ref={ref}>{value}</span>;

}

Link to headingPerformance: Using React Server Components

The BFCM dashboard is built mostly using React Server Components (RSCs). The only client components needed were ones that did animation. By using RSCs, we were able to simplify our data-fetching logic.

In a typical client-side app, we would fetch data using a combination of useState and useEffect:

const [data, setData] = useState(null);

useEffect(() => setData(getData()), []);

Fetching data on the client results in:

  1. Data being delayed until the user’s browser can download, parse, and execute JavaScript

  2. The data fetching itself being dependent on the user’s internet connection

Performance aside, client-side fetching also means we would need to implement and expose API endpoints for the client to get data.

export async function GET() {

return getData();

}

With RSCs, we were able to move data fetching to the server using async/await:

async function Statistics() {

const { value, rateOfChange } = await getData();

return <Counter value={value} rateOfChange={rateOfChange} />;

}

By calling getData directly in the component, we eliminate the need for API endpoints. As a result, users received only what they need—the fully rendered components—with no additional calls on initial page load.

Final counting animationFinal counting animation

Final counting animation

Link to headingSummary

Building data-heavy websites that are cost-efficient, performant, accurate, and have a good user experience is possible by addressing performance bottlenecks one step at a time:

  • Making queries more efficient by getting the incremental count instead of total count

  • Using ISR to minimize the number of database calls

  • Giving users dynamic visuals with rate-of-change tactics

  • Ensuring accuracy with dynamic rate adjustments

  • Moving data fetching to the server for better performance

Even the most demanding sites can use Vercel and Next.js to create great experiences. We hope this behind-the-scenes exploration of the BFCM dashboard's architecture provides valuable insights for your own site.

Prepare for BFCM 2025

If you’re looking ahead to next year’s BFCM, watch the recording of our Black Friday 2025 virtual event hosted by Vercel CTO Malte Ubl.

Watch now