MoreRSS

site iconXuanwo | 漩涡修改

ASF成员,Apache OpenDAL PMC主席,Rust贡献者,倡导数据自由。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

Xuanwo | 漩涡的 RSS 预览

How I Coding? (Nov 2025 Edition)

2025-11-28 09:00:00

Hello everyone, welcome to my November 2025 edition about How I Coding. We just went through a wild month with many new SOTA models released:

  • gpt-5.1
  • gpt-5.1-codex
  • gpt-5.1-codex-max
  • gemini-3-pro
  • claude-opus-4.5

Sadly, I didn't have a chance to evaluate them all. It doesn't make sense to just test one or two tasks on new models and throw out random ideas to my readers. This month's edition will focus only on the GPT services of models and my experiments with them, as well as the new changes to my toolset.

I didn't keep up with the latest models, but I think it's more honest and more valuable for your time.

Mindset

Prompts Raising Again

I used to believe that prompts didn't matter. It was more important to give the models correct and valuable context. I always thought that if you needed to tune prompts to get the model to behave correctly, it was time to upgrade to a new model.

However, my recent experience with gpt-5.1-codex-max has changed this idea a lot. I now think prompts are rising again in importance for agentic coding.

There are two reasons for this shift.

First, model capability keeps growing. New models align better with user input. For models that strongly prioritize following instructions, incorrect prompts make it much easier for the model to behave incorrectly.

This is especially obvious with gpt-5.1-codex-max, and even more so with higher reasoning tasks. I used to write instructions like "think from first principles, check in with the user when you hit blocks." But codex-max with xhigh will ask for clarification at every step.

I fixed this by polishing the AGENTS.md file to better guide codex-max's behavior.

This makes me think that different models may increasingly develop distinct characteristics. As users, we'll need to identify and refine our prompts to match each model's style.

Second, in agentic coding, the model usually finds its own context. The first prompt is the most important thing for the agent to perform tasks correctly. So in agentic contexts, context mainly comes from the user's prompt itself. Better prompts lead to better outputs.

In conclusion, it's worth stepping back and polishing the AGETNS.md for a while. Also there's a tradeoff here. We're software engineers with real problems to solve, and it's unacceptable to spend too much time on prompts instead of our actual work.

Optimize AGENTS.md

I suggest everyone optimize the AGENTS.md in a feedback loop. I optimized it this way:

First, follow the prompt guidelines from OpenAI and Anthropic to get a general sense of how models behave.

Then ask gpt-5.1-pro for detailed suggestions.

Pick a task that represents your daily work. This task shouldn't be too easy, something can fix in one loop, nor too complex that hard to evaluate quickly. The best tasks take 3 to 5 rounds of discussion and can be evaluated in seconds.

Observe the agent's behavior, not just speed or accuracy. Pay attention to how the model acts when it hits a block. Notice how it responds when you point out its mistakes.

Record your findings and repeat the loop until the model behaves the way you want.

Optimize whenever you switch to a new model or tool. It's also useful to check in every month.

But one thing to remember: don't spend too much time on this. LLMs are generating, not thinking. You can't fully control exactly how they behave. If you spend hours and the model still doesn't work as you'd like, try a different one.

Toolset

I'm using gpt-5.1-codex-max with high for now because I found xhigh on codex-max always overthinks and follows instructions too strictly.

Starting from the end of this month, I switched from xlaude to Conductor.Conductor can create parallel Codex and Claude code agents in isolated workspaces. It essentially does the same thing as xlaude but with a much better UI and UX.

In Conductor, you can create new workspaces for a given project with one click. Each workspace is a worktree: an entirely isolated copy of your codebase. Within a workspace, you can create multiple tabs to run agents on the same codebase, which is great for research and review.

One nice feature Conductor provides is the ability to share context between tabs.

As shown in the picture, if you start a new tab in an existing workspace, you can just add context inside the new tab so you can continue the discussion or spawn other tasks.

Conductor has built-in code review features where you can ask about code changes without copying the code.

Conductor also lets you open the editor or terminal directly from a given workspace. That's my favorite feature. I used to open Zed to review changes while work is being done.

Conductor also provides nice integration with GitHub and Linear.

I won't share all nice features one by one here. It's free to use for now, just go to https://conductor.build to give it a try.

Tips

Benchmarks can't reflect a model's real experience.

The most important tip I want to share is that benchmarks can't reflect a model's real experience. A model could be super smart and solve the hardest math problem but still fail to follow instructions correctly, or just write code full of Any.

I suggest everyone build their own evaluation system, a small one that reflects their daily work to understand how well the model fits their actual needs.


That's all, Hope you're enjoying the coding as before!

How I Coding? (Oct 2025 Edition)

2025-10-24 09:00:00

Just one week after I published my Setp 2025 edition of How I vibe coding, Anthropic released Claude Sonnet 4.5. That's a quick reminder that in this field, SOTA doesn't stay still. This post updates my mindset after a month with the new model.

Mindset

There is one addition to my mindset: slow is fast.

The more time I spend on coding, the more I realize that attention is my most important resource. The bottleneck is increasingly becoming which task I choose to focus on. Faster models don’t necessarily make people more productive, they consume attention rather than free up capacity.

There is a matrix around quality and speed: {high, low} * {quality, speed}. Obviously we should avoid low quality and low speed, but high quality and high speed is not achievable. The tradeoff then comes down to choosing quality or speed, that’s the question.

My understanding now is that quality is the most important thing. It's more acceptable to me that a model is slow but produces high quality results. At the current stage, attention is my most valuable resource, and I need to allocate it wisely. A slow but correct model consumes less of my attention and lets me focus on finding the right path. A fast but flawed model drains all my attention just to fix its errors, remove unnecessary comments and tests, or correct the lies it keeps telling.

The improvement brought by model updates seems smaller and smaller. Claude Sonnet 4.5 may be better than Claude Sonnet 4, but still not as good as Claude Opus 4.1. I believe people like Claude Sonnet 4.5 mainly because it is much cheaper and faster than Claude Opus 4.1. People said that Claude Sonnet 4.5 is good enough. But I don't think so after stuck in a dead loop for long time. Now I care more about quality than cost (both in money and time).

A fast model that drains my attention is slower in the long run. Slow models that get things right free me to think, and that’s what real speed feels like.

Toolset

No change, still using codex, xlaude and zed.

More details could be found at Setp 2025 edition

One experiment I tried this month is using Codex via Cloud, Slack, and GitHub. Here are my thoughts:

Codex From Cloud

It’s tempting to spawn tasks over the cloud, just delegate and walk away. I can monitor progress from my browser or phone, which feels convenient.

But it doesn’t work well for me because:

  • Setting up the environment is still hard and time consuming. There are many assumptions about tools that should be available in context. Some projects require complex setups for multiple services, which Codex doesn’t handle well.
  • The runtime environment has very limited resources. Building and compiling Rust code is painfully slow.

As a result, I rarely use Cloud Codex for real tasks. The only useful cases I’ve found are for asking questions and exploring codebases—like querying the system as if it were an architect. These tasks aren’t time sensitive, so running them in the cloud feels cozy. I just check the results later.

Codex From Slack

I integrated Codex into our team’s Slack. But it’s still at a very early stage: It’s just a quick shortcut to start a new task. All you get are two notifications: “I’m running” and “I’m finished.” It can’t submit PRs directly from Slack, can’t comment on results in chat, and can’t hold a conversation. Every operation requires clicking through to the Cloud task page.

This design makes Slack Codex integration far less useful than I expected. I haven’t tried Cursor yet, does it work better?

Codex From GitHub

Codex also has GitHub integration: you can enable Codex reviews and request changes. But again, it’s essentially just a way to trigger a Cloud Codex task. The overall UX is underwhelming.

That said, I’ve noticed that Codex’s code reviews are surprisingly high quality. It catches real, important bugs in PRs, not the meaningless nitpicks that GitHub Copilot often delivers. When everything looks fine, it just leaves a simple 👍. I like this approach.

The maintainer still needs to review PRs themselves, but CodeX reviews have at least been helpful instead of adding more work for maintainers. I believe it’s already a big improvement.

Tips

Subscription-based plans have become mainstream

Today, Kimi announced a coding plan for users. Nearly all major model providers have shifted to subscription-based models. I believe this is the trend. Just like how everyone now uses mobile data plans instead of paying per GB. That’s human nature: people prefer predictable, affordable pricing.

This shift also pushes service providers to improve cost efficiency and quality. I’m not overly concerned about providers “dumbing down” their services because the market is fiercely competitive. Reducing quality means losing users to competitors.

Focus on SOTA

One of my friends complains there’s too much new stuff to keep up with every day. I agree. It’s true. But you can allocate your attention wisely: focus only on SOTA models and use the best available in your daily work. Don’t get caught up in debates over whether Model A is better than Model B on Task X.

We are developers. Our attention is our most valuable resource. Allocate it carefully. It’s not our job to hunt down the absolute best models, the market will reveal them. Sometimes it’s unclear what’s truly the best, but SOTA is easy to identify. As of now, the top choices are OpenAI, Anthropic, and Google. I’m not including Qwen since Qwen3 Max isn’t affordable for coding use. Pick one from these three based on your preference.

Reevaluate this decision every one to three months. At other times, you’re still a developer. AI news should occupy no more than 10% of your input information. Focus instead on your language, tools, frameworks, and industry trends.


Hope you're enjoying the coding as before.

How I Vibe Coding? (Sept 2025 Edition)

2025-09-22 09:00:00

I wrote How I vibe Coding? back in June. Nearly three months later, things have changed. Time to update this article to reflect my current setup. In this piece, I’ll share how I use my tools to do vibe coding. As always, I’m writing this down not just to document my journey, but to inspire you and welcome your feedback.

Toolset

My current toolset consists of codex, xlaude, and zed.

From claude code to codex

I switched from Claude Code to Codex solely to access GPT-5-High, and now there's a better version called GPT-5-Codex-High. I’m not happy with Claude’s recent drama, and I’m glad GPT-5-High is outstanding. It’s on par with Opus 4.1, if not better.

Some obvious good points about GPT-5 I can tell:

  • GPT-5 is more honest. I rarely encounter cases where it claims to have done something it didn’t. It even calls git status -sb to check the diff properly.
  • GPT-5 follows instructions better. It’s hard to stop Claude from making unwanted code changes, but GPT-5 adheres to those constraints much more reliably.
  • GPT-5 is more concise. It often uses fewer tokens to answer and avoids adding comments for every line of code.

Codex doesn’t have the ecosystem that Claude Code offers, and its agentic workflow isn’t as rich. It only just added resume support and still doesn’t support resumes based on project paths. Generally, I think Codex isn’t as strong as Claude Code, but the gap is shrinking fast. The team behind Codex has been doing great work lately. Still, Codex has some clear advantages:

  • Codex is open source, so I know exactly what it does and can tweak parts to align with my needs.
  • Codex is written in Rust, so it uses far less memory than Claude Code. This is a big plus when running multiple agents.
  • Codex seems to have excellent context management. I’ve seen cases where it handled 2.4M tokens yet still had 24% context capacity left.

Overall, I’m happy with this switch to a better model even if the agent capabilities are slightly worse.

Introduce xlaude

Xlaude, Xuanwo’s Claude Code, is a CLI tool I built for myself to manage Claude instances using git worktrees for parallel development workflows. Originally designed for Claude, it now supports Codex too.

Whenever I need to work on something, I run xlaude create abc. Under the hood, it does this:

  • Creates a new git worktree named <project>-abc in the parent folder of <project>
  • Starts Codex within that worktree

When I’m done, I run xlaude delete to remove the worktree.

Xlaude also includes a dashboard powered by tmux that runs Codex inside a persistent session, so I don’t lose my work if I accidentally close the terminal. But these days, I prefer the simpler xlaude create command. It’s easier to track. Another great feature is its list of active worktrees, so I never lose sight of ongoing projects.

Sticking with Zed

I’m now running Codex inside Ghostty directly instead of using Zed’s terminal tab. After spending more time with the code agent, I’ve realized I don’t need an IDE open 80% of the time. I only need it in two scenarios: when a task is nearly complete and I’m ready to review, or when a task fails and I need to dig deep to understand what’s going wrong and guide the code agent on what to do next.

Zed is perfect for these two cases. I can open Zed in the current directory from Ghostty by typing zed .. It starts instantly, letting me keep my train of thought without losing momentum while waiting. Zed also offers excellent diff views at both the project and file levels. The overall review experience is pretty great.

So in conclusion: I’m using Codex + Xlaude + Zed for vibe coding. Codex for coding, Xlaude for task management, and Zed for code reviewing and trouble shooting.

Mindset

It’s interesting that my mindset hasn’t changed much since three months ago. LLMs are still pretty much like a recent graduate at a junior level, maybe a bit sharper but still junior. As the driver, we still need to stay in control of the task and be ready to take over anytime.

Here’s what I’ve learned this year:

  • Don’t trust benchmarks. This applies to all areas, not just AI. We don’t use code agents the way benchmarks suggest, and most benchmarks don’t cover our actual use cases. Just test models in your real scenarios and see if they feel like a good copilot. Don’t base your decisions on benchmarks alone.
  • Don’t believe in prompt engineering. Sure, prompt engineering can help sometimes, but mostly you shouldn’t obsess over it. Focus on your real business problem and context. If you find yourself spending more and more time tweaking prompts or forcing the model to do what you want, that model isn’t right for you. Find a better one.

Tips

GPT-5-Codex-High is the best vibe coding model (for now)

Three months ago, Claude Opus 4 was unbeatable. Then Opus 4.1 came out and was slightly better. But now, in September 2025, GPT-5-Codex with high reasoning is superior. The best part is you only need ChatGPT Plus at $20 to access the top coding model. With Claude, people can only use Sonnet 4 on the Pro plan at $17; to get access to Opus, you need at least the Max plan at $100.

MCP is still a lie

Three months later, MCP for coding is still a lie. People don’t really need MCP. Any MCP can just become a plain CLI or simple curl call, which LLMs have already mastered. Adding too many MCP servers is just a waste of context.

Use tools instead of configuring MCP servers in coding.

Use subscription-based pricing.

Subscription is the future. Code Agent is designed to be token-intensive. Just subscribe to the best model you want instead of paying per request or token. It makes no sense anymore. I especially can’t understand why anyone pays over $200, even $1000, for Cursor or APIs. By simply switching to subscription-based services, you achieve massive cost savings.

More and more subscription services are emerging. OpenAI lets ChatGPT users access Codex, and Cerebras has announced Cerebras Code with a similar pricing strategy. GLM also have their own plans. It’s not hard to predict that Google will soon join this battle and let Workspace users access Gemini.

Stop paying for tokens. Use subscription now. By the way, don’t pay yearly. Stick to monthly. Always stay ready to switch to a better option.


Hope you're enjoying the coding vibes: create more, hype less.

Learn Rust by Reasoning with Code Agents

2025-08-06 09:00:00

It's often said that Rust has a steep learning curve. I disagree with this notion. I'm a strong believer in learning by doing. Rust is a programming language, and like any language, it should be learned by applying it to real projects rather than relying solely on books or videos. However, learning by doing can't solve every problem that newcomers might encounter. While it helps with grasping the basics, when it comes to mastering Rust's advanced features like ownership, traits, lifetimes, async, we need more than just hands-on practice. We need to understand. We need to reason. Thanks to Code Agents, I discovered something even better: learning Rust by reasoning (with Code Agents).

What’s reasoning?

When we reason with code, we're doing more than just following its execution. We're trying to piece together the thought process behind it. We're imagining the mindset of the person (or the AI) who created it, and questioning it.

Reading Reasoning
"This line uses Pin<&mut Self>." "Why do we need Pin here? What breaks if we remove it?"
"Here we use a match statement." "Why not if let? Would it change the behavior?"
"The field is wrapped in Arc." "Is sharing needed? Who else uses this data?"

Reasoning always involves a question, not just a fact. The power of AI-assisted programming is not in generating code. It’s in giving us something to reason about.

Reasoning mimics how we truly understand complex systems.

  • We retain better. When we ask "why?", our brain connects the new idea to our existing model.
  • We go beyond syntax. Books teach language rules; reasoning teaches engineering judgment.
  • We practice thinking like a Rust developer. Not just writing "working" code, but writing "good" code.

A Reasoning-Driven Learning Loop looks like the following:

  • Get (Generate) a diff: Use a code agent to generate a small but non-trivial PR.
  • Skim and find the edge: What part of the diff feels unfamiliar or slightly suspicious?
  • Ask "why" and "what if": Why was it written this way? What would happen if I changed this?
  • Ask for runnable examples: Show a minimal version of this concept. Run it. Tweak it. Break it.
  • Repeat: Each loop deepens our understanding, not just of Rust, but of design choices.

This is not passive consumption. This is active debugging: not of the code, but of our understanding.

Not all diffs are equally educational. Here’s what I look for:

  • Unexpected constructs: Traits, macros, async blocks, lifetimes, Pin, etc.
  • Non-obvious design choices: Wrapping types in Box, using trait objects, error handling via thiserror, etc.
  • New concepts I haven’t mastered yet

Sometimes it’s just one line, but one line is enough if we go deep enough.

A Practical Example

Let's try it step by step.

First, we need an idea to work on or a problem to solve. It should be moderately challenging, not as simple as fixing a typo or renaming a type, but not so complex that it turns into an entire project. Ideally, it could be something like a PR with about 250 lines of code that is self-contained.

If you don't have an idea, feel free to pick an issue from Apache OpenDAL so you can contribute to open source while learning Rust!

I will use an example from OpenDAL. Let's take the good first issue: Migrate all layers to context-based as an example.

First, we need to discuss with the maintainer about the issue and the general idea of how we can implement it. Then, we will start Claude Code. Note that we are currently Rust newbies, so let's focus on getting Claude code working on this issue first before reasoning through it.

Claude's code will address this issue and handle the work behind the scenes. Let's just prepare a cup of coffee and wait for them for a while. We might be interrupted a few times if something goes wrong, but eventually, we'll have a basic implementation. Remember to ask Claude to run cargo clippy to ensure the code compiles.

Don't rush here; our work has just begun. Please NEVER submit a PR without thoroughly reasoning it out. Otherwise, it could waste time for both us and the maintainer.

We will need to review the code line by line. Let me give you an example. In this PR, we have a manually implemented Stream:

impl<S, I> Stream for LoggingStream<S, I>
where
 S: Stream<Item = Result<Buffer>> + Unpin + 'static,
 I: LoggingInterceptor,
{
 type Item = Result<Buffer>;

 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
 ...
 }
}

There are many new concepts for a Rust beginner: Unpin, Pin, Poll, Context. Let's focus on the first one: what does Context mean here? What happens if I don't pass it correctly in inner.poll_next_unpin()? To prevent Claude from interpreting our questions as a code improvement suggestion, it's better to make a git commit first and then ask Claude clearly.

I’m a rust learner and I’m just learning by reasoning your code. Please tell me what’s the context means in the Stream trait impl? What if I didn’t pass it done in the inner.poll_next_unpin()?

Most of the time, Claude can provide good explanations like this one. However, the most important thing is that you must keep reasoning and not trust them without verification. Sometimes, you might need to ask Claude to provide runnable examples and repeat the process. It can be challenging at first, but most of your problems will disappear after several iterations. You'll also find that more and more of your reasoning becomes project-related and not just about Rust.

When that happens, enjoy programming by reasoning with code agents.

Conclusion

Why does this method work? I believe it aligns with how humans think and understand concepts. By reasoning through existing code, we learn how code is actually written in the real world and connect it with the pieces already in our minds. Most importantly, we transform the learning process so we can focus only on what we don't understand or have concerns about, instead of repeatedly reading what we already know. This saves a lot of time compared to reading entire books just to answer one small question.

Code agents are not here to replace our learning. They are here to generate raw materials for our thoughts. Learning Rust by reasoning is not about trusting the AI. It's about building our own judgment on top of it.

The last thing I want to emphasize is: reasoning comes first! Don’t generate low-quality PRs in this way. We must put our own thinking into it and take responsibility for the results. We are the captain. AI can help generate routes for us, but We must decide the next actions ourselves.

Try it Yourself

If you want to try reasoning with a real-world issue, welcome to checkout OpenDAL good first issues

Generate a diff. Ask why. Ask what if. And don’t stop until it makes sense.


That's all, thanks for reading and happy learning!

RBIR: An Aurora DSQL story

2025-07-24 09:00:00

I've been pinged by @vaibhaw_vipul to read and share my thoughts on Just make it scale: An Aurora DSQL story. It's actually quite enjoyable. I agree with @iavins's comment that "It's less about database development and more like a love letter to Rust."

I've talked about rewrite bigdata in rust (RBIR) quite a lot, and this article offers great examples for my theory: Rust is a good choice for data-intensive infrastructure. It's time for us to rewrite bigdata in Rust.


While each database service we’ve launched has solved critical problems for our customers, we kept encountering a persistent challenge: how do you build a relational database that requires no infrastructure management and which scales automatically with load? One that combines the familiarity and power of SQL with genuine serverless scalability, seamless multi-region deployment, and zero operational overhead? Our previous attempts had each moved us closer to this goal. Aurora brought cloud-optimized storage and simplified operations, Aurora Serverless automated vertical scaling, but we knew we needed to go further. This wasn’t just about adding features or improving performance - it was about fundamentally rethinking what a cloud database could be.

As a brief background, Aurora DSQL is a serverless, distributed SQL database built on PostgreSQL. It is well-suited for global operations and highly consistent, distributed OLTP workloads. Comparable products include Google Cloud Spanner, CockroachDB, and TiDB.

To validate our concerns, we ran simulation testing of the system – specifically modeling how our crossbar architecture would perform when scaling up the number of hosts, while accounting for occasional 1-second stalls. The results were sobering: with 40 hosts, instead of achieving the expected million TPS in the crossbar simulation, we were only hitting about 6,000 TPS. Even worse, our tail latency had exploded from an acceptable 1 second to a catastrophic 10 seconds. This wasn’t just an edge case - it was fundamental to our architecture. Every transaction had to read from multiple hosts, which meant that as we scaled up, the likelihood of encountering at least one GC pause during a transaction approached 100%. In other words, at scale, nearly every transaction would be affected by the worst-case latency of any single host in the system.

GC pauses are real. We talk about GC every day, which makes it seem like a well-solved problem, but it's not. In high-load distributed systems, this can be a serious issue that renders your system unusable. As the author mentioned: "they were very real problems we needed to solve"

The language offered us predictable performance without garbage collection overhead, memory safety without sacrificing control, and zero-cost abstractions that let us write high-level code that compiled down to efficient machine instructions.

Well, it's boring, right? I know some friends who almost experienced PTSD when it comes to "memory safety", but please let me expand the discussion about memory safety in C and C++ one last time.

Many people treat this as a skill issue, claiming that it's possible to write memory-safe code in C and C++ as well. I believe them. I trust that they can write memory safe C in right projects, with the right people, at the right time.

I emphasize right here because I also recognize that they're human (correct me if I'm wrong!). Humans make mistakes. Some projects might lack documentation, so we may not realize we need to read within a 1024-byte limit; sometimes new team members join and aren't yet familiar with the hidden context; or there are days when we simply can't think clearly.

In other words, while we can write safe code in C or C++, Rust ensures our code is safe through zero-cost abstractions. That changes everything. As a reviewer, we no longer need to catch every pointer usage. Instead, we can focus on reviewing business logic.

Returning to the title of this article: just make it scale. Rust is a scalable language; it can grow with our team and our project's size.

Rather than tackle the complex Crossbar implementation, we chose to start with the Adjudicator – a relatively simple component that sits in front of the journal and ensures only one transaction wins when there are conflicts. This was our team’s first foray into Rust, and we picked the Adjudicator for a few reasons: it was less complex than the Crossbar, we already had a Rust client for the journal, and we had an existing JVM (Kotlin) implementation to compare against.

Good choice.

I've seen many teams fail when migrating to Rust because they try to switch everything at once. They send out a team message saying, 'Hey everyone, we're rewriting everything in Rust now!' Soon after, they find their team burning out quickly: they need to learn an unfamiliar language to build features, and they still have to be oncall for the old services. It can be really tough.

Starting with a small project or module within your existing projects is always a great idea. It allows you to evaluate Rust's value and gives developers some time to learn Rust first.

But after a few weeks, it compiled and the results surprised us. The code was 10x faster than our carefully tuned Kotlin implementation – despite no attempt to make it faster. To put this in perspective, we had spent years incrementally improving the Kotlin version from 2,000 to 3,000 transactions per second (TPS). The Rust version, written by Java developers who were new to the language, clocked 30,000 TPS.

I've decided not to comment on this too much. THIS IS RUST, guys.

We decided to pivot and write the extensions in Rust. Given that the Rust code is interacting closely with Postgres APIs, it may seem like using Rust wouldn’t offer much of a memory safety advantage, but that turned out not to be true. The team was able to create abstractions that enforce safe patterns of memory access.

I wonder if they are using pgrx or simply building a Rust API against Postgre's C API.

At first, things went well. We had both the data and control planes working as expected in isolation. However, once we started integrating them together, we started hitting problems. DSQL’s control plane does a lot more than CRUD operations, it’s the brain behind our hands-free operations and scaling, detecting when clusters get hot and orchestrating topology changes. To make all this work, the control plane has to share some amount of logic with the data plane. Best practice would be to create a shared library to avoid “repeating ourselves”. But we couldn’t do that, because we were using different languages, which meant that sometimes the Kotlin and Rust versions of the code were slightly different.

I wonder if they've considered implementing it in Rust and exposing it through JNI. It seems natural to me, but I'm not sure why they didn't mention this option in the post.

Rust turned out to be a great fit for DSQL. It gave us the control we needed to avoid tail latency in the core parts of the system, the flexibility to integrate with a C codebase like Postgres, and the high-level productivity we needed to stand up our control plane. We even wound up using Rust (via WebAssembly) to power our internal ops web page.

This statement reminds me of Niko Matsakis's Rust in 2025: Targeting foundational software.

I see Rust's mission as making it dramatically easier to create and maintain foundational software.

Rust is an excellent fit for foundational software like DSQL and your project!

We assumed Rust would be lower productivity than a language like Java, but that turned out to be an illusion. There was definitely a learning curve, but once the team was ramped up, they moved just as fast as they ever had.

Given the popularity of code agent tools like Claude Code, I want to point out that Rust is especially well-suited for vibe coding.

It's quite easy for Claude Code to use tools like cargo clippy to build and fix compiler errors in Rust code. Users just need to provide the correct instructions for code agents. Once it builds and passes all tests, we can use it with confidence, without worrying about memory safety or runtime type mismatches.

Worth a try!

Conclusion

Rust is hyped for solid reasons. It's a foundational language. Welcome it, embrace it, enjoy it!

Thank you, Databend; Hello, LanceDB

2025-06-29 09:00:00

TL;DR: I'm leaving Databend to join LanceDB.

Thank you, Databend

I still remember the day I spoke with Bohu about joining Databend. It was a winter day with the sun shining brightly (Actually, I don't really remember if it was sunny and bright). We talked a bit about data warehouses, Rust, Snowflake, and open source. It was a time before AI, lakehouses, and table formats.

In the years at Databend, I went through my fastest growth both in life and in tech.

During my years at Databend, I married my wife, who has become the center of my life. We bought a cozy house near Tianjin, where we live with our two lovely dogs (Naihu and Theo) . Databend witnessed every major milestone in my personal life.

At the same time, Databend stood behind every milestone in my career.

OpenDAL entered and then graduated from the ASF Incubator; I was nominated as an ASF Member, and I was invited as a committer for iceberg-rust, etc. If QingCloud was a school that taught me how to work, then Databend is the place that allowed me to shine and fully realize my potential.

Databend is now entering a new and steadier phase, exactly what we set out to build back in that Rust-and-Snowflake conversation with Bohu. My heartbeat is still synced to the 0 → 1 phase. Designing protocols, chasing regressions, turning bold ideas into first commits. So I chose to hand over my modules while everything is smooth. I leave with deep gratitude, knowing that Databend's codebase, and the friendships behind it, will continue to grow long after I step aside.

My next adventure is LanceDB, where vector lakes meet Rust. Different waves, same ocean.

Hello, LanceDB

Readers may know that my personal vision is Data Freedom, and I am currently working on Rewriting Big Data in Rust. I really don't want to work at a big tech company (honestly, I'm not sure I could pass the interview), and I also don't want to become a competitor to Databend (even though they haven't asked me to sign an NCC—I just don't want to).

LanceDB appeared: LanceDB is an open-source multimodal database designed for efficient storage, retrieval, and management of vectors and multimodal data. It's quite appealing to me to create a new format that could set the standard for the new AI era. Concretely, Lance's columnar container layout and on-disk HNSW index open a playground for Rust-level SIMD tuning, exactly the kind of hard-core storage work I've been missing. I would have the opportunity to work on low-level storage optimizations to support vector search and unstructured data storage. This would also be a great chance to learn many new things.

LanceDB is strongly committed to open source. By joining LanceDB, I could stay active in many open source communities like opendal, arrow, datafusion, iceberg, and even databend in the future. I could still connect them all to build something truly fantastic.

Joining LanceDB feels like the most straightforward way to achieve that vision of Data Freedom, one vector at a time.


TL;DR in one line: grateful waves goodbye, curious waves hello. See you at the next PR review — perhaps in LanceDB, perhaps back in Databend, always in open source.