NewDays brings its AI-driven dementia care platform to Nevada, expands seed round to $16M

https://cdn.geekwire.com/wp-content/uploads/2026/09/NewDays-founders1.jpg

NewDays founders Daniel Kelly (left) and Babak Parviz. (NewDays Photo)

NewDays, a Seattle startup using a generative AI therapy to treat people with mild dementia, has raised additional funding and closed its seed round with $16 million. The funding was led by Madrona and General Catalyst.

The company also announced on Wednesday that it has expanded its services to Nevada, joining Washington, California, Florida, Texas and New York. NewDays offers telehealth visits with human clinicians once or twice a month alongside unlimited conversations with an AI companion named Sunny.

“Our goal isn’t to add years — it’s to add quality to the years people have,” said CEO and co-founder Babak Parviz.

The startup is addressing a widespread issue: one in three Americans over 65 experiences cognitive decline, with 11% living with dementia and another 22% with mild cognitive impairment. Patients use Sunny to engage in conversational topics, memory exercises, and language or reasoning games designed to strengthen cognitive function.

While these cognitive strategies are clinically proven, they have historically lacked broad accessibility, Parviz said. NewDays aims to make treatment scalable using AI and demonstrate measurable improvement.

This past July at the annual Alzheimer’s Association International Conference, the company presented research showing that NewDays patients with dementia performed better on cognitive tests than expected historical decline curves — translating to roughly 18 months of preserved cognitive function. The study was limited to 24 patients, half of whom have dementia and the other half experiencing other cognitive impairment.

“Generative AI under the guidance of an expert human clinician is what finally lets us deliver a medically proven intervention at that scale. That’s the whole thesis of the company,” Parviz said via email.

To further validate its platform, NewDays is currently running a randomized controlled trial with Kaiser Permanente in California.

Users can try Sunny for free before opting into a 20-minute clinical assessment to evaluate suitability for the full program. Clinical sessions cost $150 each. NewDays currently accepts traditional Medicare as an out-of-network provider and is working to secure in-network status with commercial insurers and Medicare Advantage plans.

GeekWire

Things You Never Knew About Everyday Products

https://theawesomer.com/photos/2026/09/product_secrets_in_plain_sight_t.jpg

Things You Never Knew About Everyday Products

From microwave popcorn to light bulbs to Kleenex, everyday products are full of interesting backstories and features you probably never heard about. Mike from List 25 explores these hidden design secrets, planned obsolescence, the stories behind how products evolved, and cases where consumer pressure forced companies to change them.

The Awesomer

Designing a Reliable MySQL Backup Strategy with Percona XtraBackup

Introduction

In a production MySQL environment, backups are not just a best practice – they are your recovery plan when something breaks.

Data corruption, accidental deletes, failed deployments, storage crashes – these are not hypothetical risks. They happen. When they do, your ability to recover quickly depends entirely on how well your MySQL backup strategy was designed.

In one of our live production environments, we implemented a Full + Incremental MySQL backup strategy using Percona XtraBackup. The objective was clear:

  • Reduce backup windows
  • Avoid performance impact on the primary server
  • Maintain consistent physical backups
  • Enable reliable point-in-time recovery (PITR)

This article explains the architecture, automation model, restoration workflow, and operational lessons learned while running this MySQL disaster recovery strategy in production.

Why Percona XtraBackup?

Logical backup tools such as mysqldump are useful for small databases. However, as data size increases, logical dumps become slower, consume more resources, and extend recovery times.

Our production environment required:

  • Hot, non-blocking backups
  • Minimal performance impact
  • Faster restore capability
  • Physical consistency of InnoDB tables
  • Flexibility to restore to a specific recovery point

Percona XtraBackup meets these requirements by performing physical backups of InnoDB data files without locking tables for long durations. Since it works at the storage level, restoration is significantly faster compared to logical imports. To understand how transaction consistency and crash recovery function internally, see the InnoDB storage engine documentation.

For high-availability MySQL deployments, physical backups are generally more practical and operationally reliable. For detailed command references and configuration guidance, refer to the Percona XtraBackup documentation.

Backup Architecture Overview

High-Level Design

  • Backup Source: MySQL Replica Server
  • Backup Tool: Percona XtraBackup
  • Backup Model: Full + Incremental
  • Retention Policy: 7 Days
  • Storage Location: Local filesystem on backup server

Backups were executed from a replica instead of the primary database server. This decision reduced production load and ensured that backup activity never interfered with live application traffic.

Using a replica for backups is a simple architectural choice, but it significantly improves operational stability.

Directory Structure and Organization

A clean directory structure prevents confusion during recovery.


/backup/mysql/
├── full/   # Weekly full backups
├── incr/   # Daily incremental backups
└── log/    # Backup execution logs

Each backup is timestamped. This makes it easy to:

  • Identify recovery points
  • Maintain incremental chain order
  • Automate retention cleanup
  • Troubleshoot failures quickly

Consistency in structure reduces recovery time during real incidents.

Backup Schedule and Automation

Manual backups introduce risk. In emergency situations, undocumented manual steps often fail.

We automated the process using scheduled cron jobs during off-peak hours.

Schedule

  • Full Backup: Every Sunday
  • Incremental Backup: Monday to Saturday (or twice daily when required)

This ensured:

  • Full backups were taken during low traffic windows
  • Incremental backups captured daily changes efficiently
  • Storage growth remained controlled
  • Recovery points were always recent

Automation also handled deletion of backups older than seven days, enforcing the retention policy without manual intervention.

Full Backup Workflow

The weekly full backup process performs the following:

  1. Creates a timestamped directory
  2. Executes xtrabackup --backup
  3. Writes execution logs for audit and debugging
  4. Removes backups older than the defined retention period

This keeps storage usage predictable and eliminates cleanup mistakes.

Incremental Backup Workflow

Incremental backups capture only the data changes since the previous backup. This significantly reduces:

  • Backup duration
  • Disk usage
  • Network load (if backups are transferred)

Determining the Base Backup

The script dynamically determines the correct base:

  • If no incremental exists, the latest full backup is used
  • If incremental backups exist, the most recent incremental becomes the base

Maintaining the integrity of this incremental chain is critical. A broken chain means restoration will fail. For that reason, monitoring and validation are part of the daily operational checklist.

Selective Point-in-Time Recovery Strategy

Backups only provide value when restoration is reliable and predictable.

This strategy supports restoring to:

  • The latest backup
  • Any specific incremental backup within the retention window

Restoration Workflow

  1. Stop the MySQL service
  2. Identify the required recovery point
  3. Prepare the full backup using --apply-log-only
  4. Sequentially apply incremental backups in chronological order
  5. Perform the final prepare phase
  6. Replace the MySQL data directory
  7. Correct file ownership and permissions
  8. Start MySQL

This structured approach ensures data consistency and allows precise recovery based on business requirements.

Point-in-time recovery provides operational flexibility, especially when recovering from accidental deletes or application-level errors.

Operational Safety Measures

During restoration, risk management is essential.

To prevent accidental data loss:

  • Existing data directories are renamed before replacement
  • Restores are performed during approved maintenance windows
  • MySQL service control is handled manually in production environments

Automation is powerful, but destructive actions in production should always include controlled human verification.

Monitoring and Troubleshooting

Logging

Each backup execution generates dedicated log files:

  • Full backup logs
  • Incremental backup logs

Daily log verification ensures backup failures are detected early, rather than during a real disaster scenario.

Common Failure Points

  • Missing backup user privileges
  • Insufficient disk space
  • Corrupted incremental chain
  • Incorrect base directory reference

Most issues were eliminated through proactive monitoring and periodic restore validation.

Key Learnings and Best Practices

Running this MySQL backup strategy in production reinforced several principles:

  • Always test restores, not just backups
  • Keep backup logic simple and deterministic
  • Separate full and incremental backups clearly
  • Automate retention enforcement
  • Never rely on production systems for restore testing

The confidence to restore quickly comes from repeated testing, not from assuming backups are valid.

Platform Compatibility

This backup strategy relies on physical file-level access. Therefore, it does not work with managed database platforms that restrict file system access.

It is suitable for:

  • On-premise MySQL servers
  • MySQL hosted on virtual machines (such as EC2 instances) with full OS access

It is not applicable to managed services where data directory access is restricted.

Understanding this limitation is essential before implementation.

Conclusion

A reliable MySQL backup and disaster recovery strategy requires more than installing a tool. It requires clear architecture, automation discipline, regular testing, and operational awareness.

By combining:

  • Percona XtraBackup
  • A Full + Incremental backup model
  • Structured directory management
  • Automated retention policies
  • Regular restore validation

We achieved predictable recovery times, reduced backup overhead, and improved operational confidence during high-pressure incidents.

For organizations managing production MySQL workloads, this approach provides a practical, scalable, and field-tested foundation for long-term data protection.

Planet for the MySQL Community

★ Best Laravel Practices for Every Developer

https://saasykit.com/open-graphy?title=Laravel%20Best%20Practices&url=https%3A%2F%2Fsaasykit.com%2Fblog%2Flaravel-best-practices&signature=af3ee76d2754edcf057e766939a37b02cf43308377862794822959c7bc1a577a&.png

Laravel is a powerful framework designed to simplify building modern web applications. Like any framework, it has best practices embedded in its core. By following these guidelines, you can write cleaner code, minimize technical debt, enhance team collaboration, and ensure your codebase aligns with the "Laravel way" of doing things.

In this article, we’ll explore these essential Laravel best practices, from structuring your code to optimizing database operations, ensuring your projects stay efficient and developer-friendly.

Whether you’re a seasoned Laravel developer or just starting, these practices will help you level up your development skills and deliver high-quality applications.

So let’s dive in. 👇

Fat Models, Skinny Controllers

Shift database logic to Eloquent models to maintain cleaner controllers and reusable code

Bad example:

public function index()
{
    $clients = Client::verified()
        ->with(['orders' => function ($query) {
            $query->where('created_at', '>', now()->subDays(7));
        }])
        ->get();

    return view('index', compact('clients'));
}

Good example:

public function index(Client $client)
{
    return view('index', ['clients' => $client->getVerifiedWithRecentOrders()]);
}

class Client extends Model
{
    public function getVerifiedWithRecentOrders(): Collection
    {
        return $this->verified()
            ->with(['orders' => fn($query) => $query->recent()])
            ->get();
    }

    public function scopeVerified($query)
    {
        return $query->where('is_verified', true);
    }
}

class Order extends Model
{
    public function scopeRecent($query)
    {
        return $query->where('created_at', '>', now()->subDays(7));
    }
}

 

Single Responsibility Principle

A class should have only one responsibility. This means that a class should focus on a single piece of functionality. Violating this principle can make your code harder to read, test, and maintain because it mixes concerns that should be separated.

By adhering to the Single Responsibility Principle, you create code that is easier to understand and refactor. Each class or service has a clear purpose, making the overall system more modular and flexible.

Bad example:

public function update(Request $request): string
{
    $validated = $request->validate([
        'name' => 'required|max:255',
        'tasks' => 'required|array:due_date,status'
    ]);

    foreach ($request->tasks as $task) {
        $formattedDate = $this->carbon->parse($task['due_date'])->toDateTimeString();
        $this->logger->info('Task updated: ' . $formattedDate . ' - ' . $task['status']);
    }

    $this->project->updateTasks($request->validated());

    return redirect()->route('projects.index');
}

Good example:

public function update(UpdateProjectRequest $request): string
{
    $this->taskLogger->logTasks($request->tasks);
    $this->projectService->updateTasks($request->validated());

    return redirect()->route('projects.index');
}

class TaskLogger
{
    public function logTasks(array $tasks): void
    {
        // Logic to log tasks
    }
}

class ProjectService
{
    public function updateTasks(array $data): void
    {
        // Logic to update project tasks
    }
}

Methods Should Do Just One Thing

A function should have a single purpose and execute it well. When a method does more than one thing, it becomes harder to understand, test, and maintain. Splitting responsibilities into smaller, focused methods makes your code more readable and easier to debug.

Bad example:

public function getFullNameAttribute(): string
{
    if (auth()->user() && auth()->user()->hasRole('admin') && auth()->user()->isVerified()) {
        return 'Admin ' . $this->first_name . ' ' . $this->last_name;
    } else {
        return $this->first_name[0] . '. ' . $this->last_name;
    }
}

Good Example:

public function getFullNameAttribute(): string
{
    return $this->isVerifiedAdmin() ? $this->formatFullName() : $this->formatShortName();
}

private function isVerifiedAdmin(): bool
{
    $user = auth()->user();
    return $user && $user->hasRole('admin') && $user->isVerified();
}

private function formatFullName(): string
{
    return 'Admin ' . $this->first_name . ' ' . $this->last_name;
}

private function formatShortName(): string
{
    return strtoupper($this->first_name[0]) . '. ' . ucfirst($this->last_name);
}

Keep Business Logic in Service Classes

Controllers should only handle HTTP requests and responses, delegating complex logic to service classes. This keeps code clean, reusable, and easier to test.

Bad example:

public function store(Request $request)
{
    if ($request->hasFile('image')) {
        $image = $request->file('image');
        $image->storeAs('temp', $image->getClientOriginalName(), 'public');
    }
    
    // Other unrelated logic...
}

Good example:

public function store(Request $request, ArticleService $articleService)
{
    $articleService->uploadImage($request->file('image'));

    // Other unrelated logic...
}

class ArticleService
{
    public function uploadImage(?UploadedFile $image): void
    {
        if ($image) {
            $image->storeAs('uploads/temp', uniqid() . '_' . $image->getClientOriginalName(), 'public');
        }
    }
}

 

Avoid Business Logic in Routes

Routes should only handle HTTP requests, not business logic. This keeps your code clean and maintainable.

Bad example

// Business logic in the route
Route::post('/article', function (Request $request) {
    $article = new Article;
    $article->title = $request->title;
    $article->content = $request->content;
    $article->save();
});

Good example

// Route delegates logic to the controller
Route::post('/article', [ArticleController::class, 'store']);

// In ArticleController
public function store(Request $request)
{
    // logic to create article
}

Use Relationships for Cleaner Code

Use Eloquent relationships to simplify and clarify how related models interact. This avoids repetitive assignments and makes the code easier to maintain and less error-prone.

Bad example

$article = new Article;
$article->title = $request->input('title');
$article->content = $request->input('content');
$article->verified = $request->boolean('verified');
$article->category_id = $category->id;
$article->save();

Good example

$category->articles()->create($request->safe()->only(['title', 'content', 'verified']));

 

Use Database Transactions for Atomic Business Operations

Transactions ensure all database operations succeed or fail as a group, maintaining data integrity.

Bad example

public function placeOrder(Request $request)
{
    $order = new Order;
    $order->user_id = $request->user_id;
    $order->save();

    $payment = new Payment;
    $payment->order_id = $order->id;
    $payment->save();
}

Good example

use DB;

public function placeOrder(Request $request)
{
    DB::beginTransaction();

    try {
        $order = Order::create($request->validated());
        $payment = Payment::create(['order_id' => $order->id]);

        DB::commit();
    } catch (\Exception $e) {
        DB::rollBack();
        throw $e;
    }
}

Avoid Queries in Blade: Use Eager Loading

Executing queries inside Blade templates leads to inefficient database calls, especially with loops. Eager loading fetches related data in a single query, improving performance and avoiding the N + 1 query problem.

Bad example

@foreach (User::all() as $user)
    
@endforeach

If you have 100 users, this triggers 101 queries: one for the users and one for each user’s profile.

Good example

// in a service class or model passed back to controller which shares that with the blade file
$users = User::with('profile')->get();

// in blade file
@foreach ($users as $user)
    
@endforeach

This triggers only 2 queries: one for users and one for their profiles.

Chunk Data for Performance

For tasks that involve large datasets, processing in chunks reduces memory usage and improves performance by limiting the amount of data held in memory at once.

Bad example

$users = User::all();

foreach ($users as $user) {
    // Process each user
}

Good example

User::chunk(500, function ($users) {
    foreach ($users as $user) {
        // Process each user
    }
});

Use Constants Instead of Hardcoded Values

Using constants will help you locate the places where this value is used in case you wanted to change it, refactor and will help you with debugging. 

Bad example

public function isAdmin(User $user): bool
{
    return $user->type === 'admin';
}

Good example

public function isAdmin(User $user)
{
    return $user->type === UserType::ADMIN;
}

Translate Strings

You’ll thank yourself in the future as your app grows if you considered translating strings from the start. All you need it to pass strings through the __() function 

Bad example

return back()->with('message', 'Your article has been added!');

Good example

return back()->with('message', __('Your article has been added!'));  // notice the call to __()

Inject Dependencies

Creating instances with new tightly couples your classes and makes them harder to test or modify. Using the IoC container allows for easier dependency injection and better testability.

Bad example

public function store(Request $request)
{
    $user = new User;
    $user->create($request->validated());
}

Good example

public function __construct(protected UserService $userService) {}

public function store(Request $request)
{
    $this->userService->create($request->validated());
}

Avoid Directly Using .env in Code

Accessing data directly from the .env file throughout your application can make your code harder to maintain and test. Instead, store values in configuration files and retrieve them using config().

Bad example

$apiKey = env('API_KEY');

Good example

// config/services.php
'api_key' => env('API_KEY'),

// Retrieve the value
$apiKey = config('services.api_key');

Store Dates as Objects, Not Strings

Storing dates as strings can lead to inconsistent formats and parsing errors. It’s better to store them as Carbon instances, which provide robust date handling. Use accessors and mutators to format dates only when needed in the display layer.

Bad example



Good example

// In Model
protected $casts = [
    'ordered_at' => 'datetime',
];

// In Blade View


Keep Code Documentation Minimal and Meaningful

Excessive documentation often clutters the code and makes it harder to maintain. Instead, rely on clear, descriptive names for variables, functions, and classes. Use comments only when absolutely necessary to explain complex logic.

Bad example

/**
 * The function checks if the given string has any white spaces
 *
 * @param string $string String received from frontend which might contain
 *                       space characters. Returns True if the string
 *                       is valid.
 *
 * @return bool
 *
 * @license GPL
 */

public function checkString($string)
{
}

Good example

public function hasWhiteSpaces(string $string): bool
{
}

 

Align on Coding Standards with Your Team

Consistent code improves readability and maintainability, making collaboration easier.

Use can Laravel Pint to automatically format and enforce coding standards. It integrates with your development workflow, so you can run it before each commit using Git Hooks.

composer require --dev laravel/pint
vendor/bin/pint

Test, Test and Test

And finally, one of the most important things you can do to ensure the reliability, maintainability, and scalability of your code is to write automated tests.

You don’t need 100% coverage of your functionality (I’d argue that’s counter productive), but at least you need to make sure that all you GET routes are covered, and the more you can add on top, the better. 

Here’s why:

  1. Catch Bugs Early: Tests help identify issues before they make it to production. Catching bugs during development is far cheaper and easier than fixing them post-deployment.

  2. Code Confidence: With proper test coverage, you can make changes to the codebase with confidence. Tests ensure that new changes don’t break existing functionality.

  3. Documentation: Well-written tests act as living documentation for your code. They describe how the system is expected to behave and can be used to understand the code’s intent.

  4. Refactoring Made Safe: When refactoring or improving existing code, tests provide a safety net that ensures no functionality is lost during changes.

  5. Improved Design: Writing tests often encourages better software design. To write testable code, you typically end up with smaller, more focused methods and classes that are easier to maintain.

  6. Collaboration: Tests make it easier for teams to work together on large codebases. They define clear expectations for behavior, reducing misunderstandings and improving collaboration.

  7. Continuous Integration: Tests are essential for implementing continuous integration and delivery workflows. Automated tests can run on every code push, ensuring that only stable code is deployed.

  8. Long-Term Maintenance: In large projects, tests help maintain stability over time, especially when the team changes. New developers can rely on tests to understand the behavior of the codebase and ensure future changes don’t break functionality.

Keep pushing, keep building! 🤘

Laravel News Links

DBeaver as a MySQL Workbench Replacement : Performance Queries

— -MySQL Workbench Performance Reports

— –From Performance / Performance Reports

— –(Administration Tab → Performance Section → Performance Reports)

— ================================================================================

— MEMORY

— ================================================================================

— Buffer pool

SHOW STATUS LIKE ‘Innodb_buffer_pool_bytes%’;

— Top memory by event

select * from sys.`x$memory_global_by_current_bytes`;

— Top memory by user

SELECT * FROM sys.`x$memory_by_user_by_current_bytes`;

— Top memory by host

select * from sys.`x$memory_by_host_by_current_bytes`;

— Top memory by thread

select * from sys.`x$memory_by_thread_by_current_bytes`;

— ================================================================================

— HOT SPOTS FOR I/O

— ================================================================================

— Top file I/O activity report

select * from sys.`x$io_global_by_file_by_bytes`;

— Top I/O file by time

select * from sys.`x$io_global_by_file_by_latency`;

— Top I/O by event category

select * from sys.`x$io_global_by_wait_by_bytes`;

— Top I/O in time by event category

select * from sys.`x$io_global_by_wait_by_latency`;

— Top I/O time by user thread

select * from sys.`x$io_by_thread_by_latency`;

— ================================================================================

— HIGH-COST SQL STATEMENTS

— ================================================================================

— Statement Analysis

select * from sys.`x$statement_analysis`;

— Statements in highest 5 percent by runtime

select * from sys.`x$statements_with_runtimes_in_95th_percentile`;

— Using temp tables

select * from sys.`statements_with_temp_tables`;

— With sorting

select * from sys.`statements_with_sorting`;

— Full table scans

select * from sys.`statements_with_full_table_scans`;

— Errors or Warnings

select * from sys.`statements_with_errors_or_warnings`;

— ================================================================================

— DATABASE SCHEMA STATISTICS

— ================================================================================

— Schema Object Overview (High Overhead)

select * from sys.`schema_object_overview`;

— Schema index statistics

select * from sys.`x$schema_index_statistics`;

— Schema table statistics

select * from sys.`x$schema_table_statistics`;

— Schema table statistics (with InnoDB Buffer)

select * from sys.`x$schema_table_statistics_with_buffer`;

— Tables with full table scans

select * from sys.`schema_tables_with_full_table_scans`;

— Unused indexes

select * from sys.`schema_unused_indexes`;

— ================================================================================

— WAIT EVENT TIMES EXPERT

— ================================================================================

— Global waits by time

select * from sys.`x$waits_global_by_latency`;

— Waits by user by time

select * from sys.`x$waits_by_user_by_latency`;

— Wait Classes by time

select * from sys.`x$wait_classes_global_by_latency`;

— Wait Classes by Average Time

select * from sys.`x$wait_classes_global_by_avg_latency`;

— ================================================================================

— INNODB STATISTICS

— ================================================================================

— InnoDB Buffer Stats by schema

select * from sys.`x$innodb_buffer_stats_by_schema`;

— InnoDB Buffer Stats by table

select * from sys.`x$innodb_buffer_stats_by_table`;

— =============================================================================

— USER RESOURCE USE

— ================================================================================

— Overview

select * from sys.`x$user_summary`;

— I/O Statistics

select * from sys.`x$user_summary_by_file_io_type`;

SELECT * FROM sys.`x$user_summary_by_statement_type`;

— ============================ END ============================================

Planet for the MySQL Community

Apple’s Kentucky iPhone glass plant will add 200 permanent jobs

https://media.appleinsider.com/gallery/68761-144869-iPhone-17-Pro-Max-display-3-xl.jpg

A Kentucky-based glass plant is poised to become a much bigger piece of the iPhone supply chain, with hundreds of both long-term and temporary jobs expected as production ramps up.

Apple has been getting glass for iPhone for 20 years from Kentucky. Specifically, in Harrodsburg, Kentucky, where the tech giant plans to expand manufacture the glass for every iPhone and Apple Watch.

Apple COO Sabih Khan and U.S. Secretary of Commerce Howard Lutnick toured Corning Inc. on Friday. The tour comes one year after Apple had invested $2.5 billion more in Kentucky, hoping to double plant jobs and triple its current output.

"Made in Kentucky. Made in America. Sold around the world," U.S. Rep Andy Barr said during the tour, according to The Lexington Herald-Leader. "We invent it here. We have the talent, and we have the manufacturing heritage. We will build it here, and we will sell it to the world."

"I want Kentucky to be the first place companies think about when deciding to make their next major American investment."

The plant currently has 350 employees, but hopes to employ 200 new hourly production jobs, alongside a handful of salaried employees in glass development. That’s not quite double the existing 350, but that’s because Corning was including construction jobs in that total.

However, Apple and Corning are planning to build a new Apple-Corning Innovation Center at the site. It is believed that construction will create 100 jobs, but those won’t last.

"At Apple, we share the administration’s commitment to producing more of the most innovative technology right here in the United States," said Khan.

"We’re expanding our U.S. supply chain, and we will continue to build on these efforts because at Apple, we believe in the power of American innovation. We believe in the ingenuity of American workers, and we believe deeply in the promise of America."

The Apple-Corning Innovation Center may be similar to Apple’s Advanced Manufacturing Center in Houston, though likely at a smaller scale.

AppleInsider News

Postgres + ClickHouse Architectural Patterns

https://severalnines.com/wp-content/uploads/2026/08/share-postgresql-and-clickhouse-1.png

The role of databases has shifted significantly as modern applications must deliver real-time analytics, dashboards, and machine learning alongside low-latency transaction processing. Handling these diverse demands with a single relational database has become unsustainable under growing data volumes. Consequently, organizations are adopting specialized database architectures where multiple engines work together based on their strengths, allowing transactional and analytical workloads to coexist without competing for system resources.

This shift highlights the combination of PostgreSQL and ClickHouse as a compelling solution for modern data platforms, with Postgres serving as the authoritative transactional system, and ClickHouse operating as a high-performance analytical platform for processing massive datasets in real time. Together, they function as complementary components connected through continuous Change Data Capture (CDC) synchronization. Before we get into the common architectural patterns, let’s briefly look at why Postgres + ClickHouse.

Why Postgres + ClickHouse?

PostgreSQL excels at Online Transaction Processing (OLTP). Utilizing mature ACID compliance, MVCC, and advanced indexing, it serves as the operational system of record for managing concurrent transactions like accounts, finance, and inventory.

In contrast, analytical workloads like BI dashboards and fraud detection require scanning millions or billions of historical records. Running these massive sequential scans continuously on a production OLTP system increases CPU, memory, and latency, ultimately degrading application performance.

ClickHouse solves this issue as a column-oriented Online Analytical Processing (OLAP) database designed for rapid queries over massive datasets. Instead of replacing PostgreSQL, ClickHouse complements it by offloading complex analytical processing.
Consequently, architectural focus has shifted from choosing between the two platforms to determine how they can work together effectively. This reflects a trend toward polyglot persistence, where specialized databases collaborate to handle distinct transactional and analytical workloads.

Pattern 1: Postgres to ClickHouse Real-Time Analytics

The widely adopted PostgreSQL and ClickHouse architecture uses PostgreSQL as the transactional source of truth while continuously replicating data to ClickHouse for analytical processing. This separates workloads without complex ETL pipelines, allowing applications and BI tools to query ClickHouse directly. Because ClickHouse is optimized for large scans and aggregations, dashboards load significantly faster while keeping production PostgreSQL tables responsive and isolated from heavy reporting risks.

This approach is ideal for real-time systems like SaaS, fintech, and IoT platforms, where fast dashboard updates are a key part of the product experience.

Architecture Overview

In a typical PostgreSQL and ClickHouse deployment, applications run transactional operations on PostgreSQL to ensure data consistency. Committed transactions are then replicated to ClickHouse via a Change Data Capture pipeline, enabling analytical queries to execute independently from the OLTP workload.

By separating the transaction plane from the analytics plane, organizations allow each database to focus on the workload for which it was designed, improving scalability, reducing resource contention, and simplifying performance tuning.

Keeping Analytics in Sync with Change Data Capture (CDC)

This architecture uses Change Data Capture (CDC) to continuously synchronize transactional changes from PostgreSQL to ClickHouse. By capturing inserts, updates, and deletes directly from PostgreSQL’s Write-Ahead Log (WAL) via logical decoding and replication, CDC avoids periodic ETL jobs, minimizing latency for near real-time operational dashboards and analytics.

Enabling this requires configuring the correct PostgreSQL WAL level and exposing individual tables via publications to stream changes.

ALTER SYSTEM SET wal_level = logical;

CREATE PUBLICATION app_events_pub
FOR TABLE
    orders,
    order_events,
    account_events;

CDC services (such as ClickHouse, ClickPipes, or PeerDB) continuously replicate PostgreSQL changes to ClickHouse, reducing data delays and operational overhead compared to traditional batch ETL.

However, monitoring operational factors like replication slots, WAL retention, schema changes, connectivity, backfills, and replication lag is essential, making latency a critical component of real-time dashboard SLOs.

Operational Readiness Checklist

Pre-production deployment of PostgreSQL alongside ClickHouse requires robust operations: identifying authoritative source tables, validating CDC pipelines, and setting replication lag alerts before dashboards rely on the data.

Schema design must transform normalized PostgreSQL tables into denormalized ClickHouse models, defining clear update/delete semantics for append-optimized engines like ReplacingMergeTree. Independently test backfills and run regular reconciliation jobs to detect sync issues early.

Finally, set clear data freshness objectives and monitor metrics like ingestion throughput, WAL growth, slot utilization, and latency, treating CDC as a production service to ensure a reliable platform.

Pattern 2: Hot / Cold Time-Series Data

In this architecture, PostgreSQL stores only recent operational data for transactional processing, while ClickHouse holds the complete historical record. A continuous CDC pipeline synchronizes changes into ClickHouse, enabling PostgreSQL to safely expire older data after verified replication.

Time-Series Data Lifecycle

Combining PostgreSQL and ClickHouse separates operational data from long-term analytical data. Organizations can store only day-to-day operational records in PostgreSQL, while continuously archiving historical data in ClickHouse via a Change Data Capture (CDC) pipeline.

In a typical deployment, PostgreSQL serves as the system of record for transactional workloads, storing recent data, e.g., the last 30 days, to support low-latency OLTP operations. Simultaneously, committed transactions are streamed to ClickHouse via logical replication and a CDC connector such as Debezium, PeerDB, or native decoding. ClickHouse maintains a complete historical archive optimized for analytical queries without affecting operational database performance.

Pattern 3: Federated Query with pg_clickhouse

Instead of forcing applications and BI tools to communicate directly with ClickHouse, PostgreSQL remains the primary SQL endpoint. The pg_clickhouse extension transparently pushes supported analytical queries to ClickHouse while preserving PostgreSQL compatibility.

Federated Query Execution Flow

Upon reaching PostgreSQL, a query is processed by the parser and query planner. The pg_clickhouse extension then automatically determines if it is a transactional (OLTP) or analytical (OLAP) workload. This routing happens before execution and is completely transparent to the application.

OLTP queries, such as inserting orders or retrieving records by primary key, execute locally within PostgreSQL to maintain ACID guarantees, MVCC concurrency control, and low-latency transaction processing.

Analytical queries, like large aggregations or historical reporting scanning millions of rows, are forwarded to ClickHouse, leveraging its columnar storage engine, vectorized execution, and compression for significantly faster performance.

Pattern 4: Embedded Analytics in SaaS Applications

Customer-facing dashboards require analytics to become part of the production application itself. Every customer request may trigger analytical queries while transactional operations continue independently. This makes CDC freshness, query latency, and workload isolation part of the application’s reliability requirements.

Embedded Analytics Operational Components

While PostgreSQL and ClickHouse serve different workloads, the success of a hybrid analytics platform depends on the operational components that ensure data consistency, low latency, and service reliability. The CDC pipeline is only one part of the architecture and operators must also continuously monitor the health of the entire data flow.

End-to-end observability is critical for production deployments. Monitoring should include PostgreSQL replication health, CDC connector status, ClickHouse ingestion throughput, query performance, storage utilization, and dashboard latency. A centralized monitoring platform enables operators to correlate issues across the entire pipeline, reducing mean time to detection (MTTD) and mean time to recovery (MTTR).

Pattern 5: Hybrid

Many production environments combine three specialized database platforms. PostgreSQL serves as the transactional system of record for business-critical operations like user management, orders, accounts, and billing. Its ACID compliance, MVCC model, and mature ecosystem suit Online Transaction Processing (OLTP) workloads requiring strong consistency.

Meanwhile, TimescaleDB handles operational time-series workloads like application metrics, IoT readings, and telemetry. Hypertables, native compression, continuous aggregates, and automated retention enable efficient storage and querying while maintaining full PostgreSQL compatibility.

For analytical processing, ClickHouse offers a column-oriented database optimized for Online Analytical Processing (OLAP). It runs complex queries across billions of rows for dashboards, BI, and trend analysis. Isolating analytical workloads prevents reports and insights from impacting operational application performance.

Postgres vs. TimescaleDB vs. ClickHouse Decision Tree

To optimize performance, scalability, and operational efficiency, a simple decision process helps determine whether PostgreSQL, TimescaleDB, or ClickHouse is the best fit for a particular use case.

Operating Postgres + ClickHouse in Production

Previously, we explored how PostgreSQL and ClickHouse complement each other through real-time operational analytics, hot/cold storage, and federated queries using pg_clickhouse. However, successfully operating them in production requires understanding Change Data Capture (CDC) behavior under failure conditions, monitoring health, preparing runbooks, and establishing clear ownership across all layers. I’ll look at the operational perspective, examining how to keep the architecture healthy, diagnose common problems, and run a reliable production platform.

Native CDC for Operators

Change Data Capture (CDC) is the foundation of PostgreSQL and ClickHouse synchronization, ensuring ClickHouse operates as a near-real-time analytical platform rather than an outdated copy. For operators, understanding its internal mechanics is essential.

In PostgreSQL, CDC utilizes the Write-Ahead Log (WAL), logical decoding, and logical replication instead of scheduled ETL jobs. PostgreSQL continuously records committed transactions in the WAL, which logical replication decodes into inserts, updates, and deletes. The process starts with an initial snapshot of existing data before transitioning into continuous streaming, keeping ClickHouse perfectly synchronized.

While modern services like ClickPipes and PeerDB simplify deployment over traditional Kafka- or Debezium-based architectures, native CDC still requires operational responsibility. Complexity merely shifts to monitoring, validation, and operational governance.

Crucially, operators must monitor logical replication slots. If a CDC consumer stops, PostgreSQL retains unconsumed WAL files, causing uncontrolled disk growth that can exhaust storage and disrupt the primary database.

A useful operational query for monitoring replication slots is shown below:

SELECT
    slot_name,
    plugin,
    active,
    restart_lsn,
    confirmed_flush_lsn
FROM pg_replication_slots;

This information allows operators to verify whether replication slots remain active and downstream consumers acknowledge changes.

Distinguishing between the initial snapshot and continuous replication is critical. Initial snapshots transfer gigabytes or terabytes of data, where replication lag is expected and should not trigger alerts. Afterward, continuous replication must meet defined freshness objectives, limiting delay to seconds or minutes.

ClickHouse managed CDC services require direct PostgreSQL connectivity and do not support proxy layers like PgBouncer, Amazon RDS Proxy, or Supabase Pooler. This must be considered during network, firewall, and infrastructure deployment.

Operational Failure Modes

The primary challenge in PostgreSQL and ClickHouse architectures lies in system interactions, making an effective troubleshooting strategy vital when incidents span multiple layers.

The most frequent operational issue is CDC (Change Data Capture) lag, which leads to stale dashboards and visible delays for users even if PostgreSQL remains healthy. Operators must monitor a range of metrics, including replication lag, slot status, WAL generation rates, ClickHouse throughput, and end-to-end freshness, rather than just basic database health.

Schema evolution also presents difficulties, as application releases regularly modify PostgreSQL tables. Because ClickHouse schemas are denormalized for analysis, schema updates require precise transformations to avoid pipeline interruptions or data gaps.

Furthermore, updates and deletes require deliberate management. While PostgreSQL modifies rows directly, ClickHouse is built for append-heavy workloads. Managing updates demands strategies like ReplacingMergeTree, version columns, or deduplication, while deletes rely on tombstones, soft-delete flags, or scheduled merges.

Query routing errors frequently impact performance; analytical queries on PostgreSQL exhaust resources, whereas point lookups on ClickHouse introduce latency. Federated query setups add further complexity, as performance hinges on whether execution is successfully pushed to ClickHouse or falls back to PostgreSQL.

Finally, security and governance grow more complex because user accounts, roles, authentication, and auditing differ between the platforms. Replicated analytical data often requires distinct access controls, encryption, and logging compared to the source transactional system.

Hybrid Operations with ClusterControl

As organizations adopt specialized databases like PostgreSQL, ClickHouse, TimescaleDB, Redis, Valkey, MongoDB, MySQL, and MariaDB, operational complexity grows. Rather than managing each technology independently, platform teams require unified tooling to support these heterogeneous environments.

ClusterControl fits this strategy by delivering unified lifecycle management, including deployment, monitoring, backup, recovery, and automation, for multiple open-source databases across on-premises and cloud environments. As PostgreSQL and ClickHouse architectures grow more common, its operational management extends well beyond simple server provisioning.

PostgreSQL management involves deployment automation, high availability, backups, PITR, replication monitoring, and upgrade planning. ClickHouse adds backup strategies, merge monitoring, storage capacity planning, and query optimization. The connecting CDC pipeline also requires production-level monitoring, health checks, and incident response.

Support teams must prepare operational runbooks before production deployment. These should document reference architectures, failure modes, CDC troubleshooting, reconciliation workflows, schema migrations, and team escalation paths.

Recommended Reference Architectures

Although PostgreSQL and ClickHouse can be combined in numerous ways, several architectural patterns have consistently emerged across production deployments.

Architecture A: SaaS Operational Analytics

This architecture positions PostgreSQL as the transactional system of record while ClickHouse powers customer-facing dashboards through near-real-time CDC replication. Optionally, pg_clickhouse provides SQL compatibility for existing applications. This pattern is particularly suitable for SaaS platforms, product analytics, billing systems, and customer usage reporting.

Architecture B: Hot / Cold Time-Series Data

Recent operational data remains inside PostgreSQL while historical records migrate into ClickHouse after successful replication. Data expiration is governed by replication watermarks rather than fixed retention schedules, ensuring historical data remains protected.

Architecture C: Federated Analytics

Applications continue connecting to PostgreSQL while pg_clickhouse pushes analytical execution into ClickHouse. This minimizes migration effort while improving analytical performance.

Architecture D: Hybrid Cloud Analytics

Transactional PostgreSQL clusters remain within customer-controlled environments while ClickHouse operates as a managed analytical platform in the cloud. Secure connectivity is established through VPNs, private networking, or dedicated links.

Production Readiness Checklist

Before deploying PostgreSQL and ClickHouse into production, organizations should validate both technical implementation and operational preparedness. Successful production environments depend as much on operational discipline as on architectural design.

Before Deployment

  • Identify authoritative source-of-truth tables.
  • Define which datasets require CDC.
  • Enable logical replication.
  • Design ClickHouse analytical schemas.
  • Define update and delete handling.
  • Establish naming conventions.
  • Validate firewall and network connectivity.
  • Review proxy limitations.
  • Plan initial snapshots and historical backfills.

During Rollout

  • Execute the initial snapshot.
  • Enable continuous CDC.
  • Compare row counts and business metrics.
  • Benchmark representative analytical queries.
  • Test failover scenarios.
  • Validate schema migrations.
  • Verify dashboard freshness.
  • Ensure retention policies do not remove data prematurely.

After Go-Live

  • Monitor replication lag continuously.
  • Observe WAL growth.
  • Monitor ClickHouse insert throughput.
  • Watch merge activity.
  • Reconcile PostgreSQL and ClickHouse data regularly.
  • Review schema drift after every application release.
  • Maintain operational documentation and escalation procedures.

Conclusion

Modern data platforms use specialized architectures where each database handles specific workloads. PostgreSQL serves as a reliable transactional system of record, while ClickHouse enables high-performance real-time analytics without impacting transactional performance.
Operating this architecture requires managing Change Data Capture, replication health, schema evolution, and data reconciliation. In hybrid database environments, platforms like

ClusterControl provide valuable unified management across multiple database technologies.
Ultimately, the future involves combining both technologies into a cohesive platform. Organizations that invest in both the architecture and its supporting operational processes will ensure long-term scalability and production reliability.

Install ClusterControl and try Postgres and ClickHouse free for 30 days

Script Installation Instructions

The installer script is the simplest way to get ClusterControl up and running. Run it on your chosen host, and it will take care of installing all required packages and dependencies.

Offline environments are supported as well. See the Offline Installation guide for more details.

On the ClusterControl server, run the following commands:

wget https://severalnines.com/downloads/cmon/install-cc
chmod +x install-cc
sudo ./install-cc     # omit sudo if you run as root

After the installation is complete, open a web browser, navigate to https://<ClusterControl_host>/, and create the first admin user by entering a username (note that “admin” is reserved) and a password on the welcome page. Once you’re in, you can deploy a new database cluster or import an existing one.

The installer script supports a range of environment variables for advanced setup. You can define them using export or by prefixing the install command.

See the list of supported variables and example use cases to tailor your installation.

Planet for the MySQL Community

Building Implosions from Above

https://theawesomer.com/photos/2026/08/implosions_from_above_t.jpg

Building Implosions from Above

It can be fascinating to watch old structures get torn down with explosives. But most footage of controlled building demolitions is shot from the side. Nelson Aerials shared this eye-opening 3-minute video compilation of 11 implosions captured from a different perspective by flying a photography drone directly overhead.

The Awesomer