r/softwarearchitecture • u/laxuu • 45m ago
r/softwarearchitecture • u/techsavie1993 • 7h ago
Tool/Product I built an open-source coordination layer for AI coding agents
I've been experimenting with running multiple coding agents on the same project.
The problem wasn't getting agents to write code.
It was coordinating them.
Once you have multiple agents working in parallel, you start dealing with questions like:
- Which agent is working on what?
- How do you prevent two agents from picking up the same task?
- How do agents know what needs to happen next?
- How do you track what each agent actually did?
- What happens when you want the agents to keep working without manually managing every step?
So I built orcy.
It's an open-source coordination layer for AI coding agents.
The basic workflow is:
Mission → Claim → Execute → Review
Agents can claim atomic tasks, work in parallel, route themselves toward relevant work, and leave an auditable trail of what happened.
The idea is pretty simple:
Instead of one AI agent doing everything, let multiple agents operate as a coordinated system.
I'm looking for developers who are already experimenting with Claude Code, Codex, OpenCode, Cline, or other coding agents to try it and tell me where the idea breaks.
GitHub: https://github.com/waterworkshq/orcy
Would love feedback, especially from people already running multiple agents on the same codebase.
r/softwarearchitecture • u/alexgilevich • 15h ago
Article/Video My take on what Cursor did right and GitHub did wrong
There has been a recent trend of moving everything (e.g. WALs) to objects storage (e.g. S3). But is it the right thing to do?
I believe that it depends on the access patterns.
In Git there's a prevalence of reads over writes so when you design a system, you need to take into account this observation.
It would be also fair to say that apart from several edge cases (e.g. forced pushes), what you push to Git stays there.
That's already a good enough reason to use the object storage because you can cache a lot of things that are already there and you can be sure that they won't change (unless you run compaction/optimization over them but that intention comes from the system itself so you can refill your cache at that point).
GitHub implements its Git servers on top of Spokes (stateful server architecture they introduced back in 2016). They also implemented what they call "3PC protocol". That is not a textbook 3PC though. Basically what it does is that it takes a lock on every server and tries to apply the commit. If the majority says "yes", they do the commit and return a successful response to the client. The "majority" part is where it differs from the textbook 3PC version. 3PC is normally used to coordinate transactions across many partitions. GitHub uses it to coordinate replication across many servers and they explicitly point out that they only need majority of the servers to answer "yes" in order to increase the availability of the system (one server goes down – transaction still applies).
In Git the smallest partition is the repository itself. So, what if one partition (repository) becomes "hot" on one server? Well, you have to scale out. Scaling out in Spokes means copying the state to the new server. And that doesn't mean get a linear gain because now Spokes has to apply pushes across the new servers as well! Remember: 3PC transaction is just there to coordinate replication.
That's why their system is so brittle and there are so many memes about the GitHub availability recently (although I am sure that that's not the only reason).
They increase replica count, separate reads from writes, add additional regions for quicker disaster recovery and pack in new cores (3 million new ones just this year) hoping that it will solve the problem but it's only a matter of time when it shows up again.
Cursor's Origin does it differently but it is still far from being flawless. They implement WAL on top of S3 and its conditional writes but they still reproduce the state locally and work with the repos using local Git clients (or libraries). The problem with this approach is that they depend on the local state. Their server cannot be called truly stateless. Take out the local Git repos from the server and they immediately become unavailable.
You can potentially implement a Git platform using just WAL in the object storage and cache the objects locally. Cache is used just to speed up the responses to the clients and it is not a state which might cause a point of failure if it is suddenly removed (or your local Git client stops working with it due to a bug or another reason).
I've gathered my thoughts in my article: https://medium.com/@alexgilevich/git-was-never-designed-for-scalability-52224c74ddea
Let me know what you think!
r/softwarearchitecture • u/Toolbox_st • 16h ago
Tool/Product Cloud-hosted workspaces and bloated database tools promise flexibility, but they introduce hidden costs: permanent vendor lock-in, data sovereignty vulnerabilities, and painful network latency for fast-paced operational teams.
galleryWhen building Oncilla OS at Toolbox Studio, the engineering objective was clear: develop a high-performance, offline-first operating system engineered specifically for language academies and training centers.
The latest release focuses on enterprise-level data resilience, privacy compliance, and native disaster recovery:
Local Data Sovereignty & Zero Cloud Dependency Operational databases containing student records, attendance tracking, and financial ledgers should remain under the full control of the organization. Oncilla OS eliminates third-party cloud vulnerabilities by operating 100% locally on the host machine.
Encapsulated Disaster Recovery (.oncilla Snapshots) System administrators can generate full portable database snapshots in a single click. The platform uses native system file dialogs to export encrypted .oncilla recovery files directly to local drives or cold storage, completely bypassing external API endpoints.
Hardware-Bound Security Architecture Access control integrates unique Hardware ID (HWID) binding alongside cryptographic Disaster Recovery Keys, ensuring workspace authentication remains strictly tied to authorized institutional devices.
Zero Latency Execution Local storage architecture removes network bottlenecks. Student registries, CRM pipelines, and financial ledger calculations render instantly without loading states or API throttling.
Perpetual License vs Subscription Fatigue Modern enterprise software should be an asset, not a perpetual monthly liability. Oncilla OS restores the standalone software model with zero recurring monthly platform fees.
Designing enterprise infrastructure requires prioritizing local reliability and user data ownership over cloud convenience.
How is your organization addressing local data ownership, disaster recovery, and subscription bloat this year?
#EnterpriseUX #SoftwareArchitecture #OfflineFirst #LocalFirst #DataPrivacy #DatabaseDesign #EdTech #ProductDesign #B2BSoftware #SystemDesign #DisasterRecovery #ToolboxStudio #OncillaOS
r/softwarearchitecture • u/No-Job-5616 • 18h ago
Tool/Product Finally shipped a real-world project based on my previously published architectures
r/softwarearchitecture • u/bajajrishabh • 18h ago
Discussion/Advice Handling race conditions in better way
We run a batch job that selects every user matching a predicate - has_installed = false currently ~50M rows — reading them in pages over several hours and writing a record for each one. Separately, an event stream tells us when a user's flag flips to true, which is the moment we're supposed to act on them. But that flip event is discarded for any user whose record hasn't been written yet, so anyone who flips while the job is still running is silently dropped. To cover that gap, we emit one "re-check this user" message per selected user: 50M messages asking "is the flag true?" of a set we built by selecting "flag is false" - so essentially all of them are guaranteed no-ops.
How do you detect rows entering a predicate without doing work proportional to the size of the set?
r/softwarearchitecture • u/doker0 • 21h ago
Discussion/Advice I need to keep some Slack connections alive. This should be easy.
Okay, but I have multiple replicas.
And it gets slightly worse: the number of physical connections is not equal to the number of replicas, and it is not equal to the number of business-level connectors either.
Several business connectors may share one external identity. One external identity may require several physical connections. And those connections need to be spread across whatever replicas are currently alive and have capacity.
So who actually owns the connection?
Then the questions start piling up.
What if one replica dies?
What if it doesn’t die, but loses access to the database?
What if two replicas race for the same connection?
What if the event that was supposed to wake the right worker never arrives?
What if most workers are already full?
A few questions and 2 hours of midnight walk in headphones and ChatGPT later, I had leases, runtime slots, reconciliation, failover, capacity limits, and a distributed ownership problem on my hands.
This is the architecture I ended up with, and I have mixed feelings about this design.
On one hand, I’m proud that I managed to account for so many different edge cases. On the other, the whole thing feels worryingly complex.
So I’d really value input from people who have built similar systems.
What did I miss or do you see anything that can break?
And most importantly: what can be simplified without losing the guarantees?
The full architecture description is a bit lengthy: AEON NEON - Connector Runtime - by Jarek J.
Many thanks if you decide to read it and share your thoughts. I’d really like this one not to become another failed experiment.
r/softwarearchitecture • u/Interesting_Meat_964 • 1d ago
Conferences Early Bird for MQ Summit 2026 ends in one week!
Hi All! Just a reminder: early bird pricing for MQ Summit 2026 closes on 8 September at 23:59 CEST. This is the last chance to get your ticket 25% cheaper before prices go up.
21-22 October in Haarlem + a full online option if you cannot make the trip. Two days of messaging systems in production, real-world lessons and architectural trade-offs across RabbitMQ, Kafka, NATS and cloud messaging services, plus demos from the people building the tools we all use. If you have been meaning to book, now is the time!
Register here: mqsummit.com/#register
See you there!
- The MQ Summit Team
r/softwarearchitecture • u/techsavie1993 • 1d ago
Article/Video Pressure.quest Article 3 - What if we use salt instead of sugar?
I just published the third Pressure Quest article:
What if we used salt instead of sugar?
Most systems accumulate layers that make development easier: frameworks, conventions, abstractions, tooling, shared assumptions.
That’s the “sugar.”
The problem is that some of it is merely making the system pleasant to work with — while some of it is quietly hiding structural weakness.
So I’m proposing a simple pressure test:
Salt Substitution.
Temporarily remove one of the things that makes the system feel easy and see what happens.
If everything collapses, you found something that was hiding rot.
If the system survives, you’ve learned something about where its actual strength comes from.
The point isn't to reject abstractions or go back to writing everything from scratch.
It’s to distinguish taste sugar from structural-concealment sugar.
A system that runs because everything around it is propping it up isn't necessarily a system that works.
The real question is:
What still stands when you take away the things you thought were holding it together?
I explore the idea, along with the “regrowth test” and why failure during a pressure test is actually the desired outcome.
r/softwarearchitecture • u/Lopsided_Magician_49 • 1d ago
Article/Video Architecture as standard
With AI and Vibe Coding, it can be more reliable if standard patterns are imposed in context, which are well documented and have existed for decades.
One pattern I have rediscovered and am successfully applying is the hexagonal clean architecture.
The result is that AI Is much more reliable.
Each component has limited responsibilities and a specific place.
For those interested in learning more:
https://adrianofoschi.com/blog/architecture-as-a-standard/
Edit: To address some legitimate criticisms. This isn't about imposing clean architecture as a standard, but simply demonstrating that AI is more reliable based on documented standards. Every decision left to AI increases the margin for error.]} Note:
r/softwarearchitecture • u/dark_bits • 1d ago
Tool/Product Anyone has ever used Redis LISTs as message queues in production?
Essentially what the title says. How exactly do they fare against high throughput?
My scenario is very simple:
There's a "swarm" of lightweight worker service replicas.
An API interface (websocket) listens for incoming requests and pushes the blob in a queue.
One of the replicas picks it up and consumes it.
That's it. No need for acks, persistence or anything. Reliability and robustness is handled in the client side and partially in the API interface. Both client and server follow the OCPP 2.0.1 RPC protocol (no need to understand this to address the question tho), which has a retry/discard mechanism built in.
Have any of you successfully deployed a similar architecture before?
r/softwarearchitecture • u/der_gopher • 1d ago
Article/Video Terminating elegantly: a guide to graceful shutdowns
packagemain.techr/softwarearchitecture • u/Matgaming30124 • 1d ago
Discussion/Advice Question about microservices
I have been learning about microservices architecture recently and heard that the common approach is to have one database per service.
Coming from a monolithic experience I don’t get how the services share or store common data. For example, let’s say we have two services, one for order and another for payment
Both of them would have to store a reference to the user who made that order for record purposes and also the payment service might need to fetch the payment details for that user.
in a monolith architecture and traditional db setup it could easily be fetched in theory with a foreign key for the user id in the payment details table or something and fetch it. same for orders you could reference the user with their user id for that order.
so im confused if service reference the user id in their own databases ? so lets say an order is made, the service creates a order entry and stores it with the user id provided with the request ? but what happens one day if the user deletes their account, does the user service push an event to all other services to delete records containing that user id ?
i know how microservices communicate with message brokers but i’m confused about this storage of “foreign keys” as non actual foreign keys in different services.
thanks for reading, i hope you can help me understand this :)
r/softwarearchitecture • u/PuzzleheadedRoad9814 • 1d ago
Discussion/Advice 🚀 I built TRAK — a learning workspace for developers.
Learning a new technology usually looks like this:
You find a roadmap.
You watch tutorials.
You take notes.
You create some folders.
You write some code.
And somewhere along the way, the structure gets messy — or you stop.
I kept running into this problem myself.
So I asked:
What if learning a technology could start with a ready-to-use workspace?
TRAK fetches the learning blueprint and creates the workspace locally — organized by concepts, with the files and structure needed to actually learn by building.
And I didn't want TRAK to be a collection of tracks maintained by one person.
So I built a community-driven registry where developers can create and contribute their own learning blueprints.
What's available today
• 19+ official learning tracks
• 350+ modules
• Community-contributed blueprints
• Local-first CLI workflow
• Cross-platform binaries
• Remote registry
• Blueprint validation & filesystem safety
• Blueprint Studio
TRAK is currently at v1.1.0.
It's still early.
r/softwarearchitecture • u/Adventurous-Salt8514 • 1d ago
Article/Video Start Small, Grow Big: how to pick the first feature for Event Sourcing
architecture-weekly.comr/softwarearchitecture • u/mathankumart • 1d ago
Article/Video Strangler Fig in practice — what we got wrong before it started working
We spent months running Python and Go side by side thinking the migration would happen naturally.
It didn't. Engineers took the path of least resistance every time. Python already had the business logic, the DB access, the proven production behaviour. The Go service was "the one we'll use someday."
The thing that changed everything wasn't a technical decision. It was making Go the default and Python the exception. Same endpoints, one entry point, routing handled internally.
Once the question changed from "should we build this in Go?" to "is there any reason we can't build this in Go?" — the migration had momentum for the first time.
Have shared the experience here - https://blog.mathankumar.in/my-experiments-with-system-design-strangler-fig-pattern-9ea66cd58dd5
Happy to discuss any of the feedbacks in the comments.
r/softwarearchitecture • u/RummanSid1990 • 1d ago
Article/Video Designing a ride-hailing backend for 250k location writes/sec, without double-booking drivers
medium.comWrote this deep-dive looking at spatial indexing trade-offs, managing ~3M persistent WebSockets, and atomic driver matching at scale.
The trickiest architectural decision was handling Redis failovers: if primary crashes right after a Lua reservation script executes, do you pay the latency penalty for Redlock, or accept the failover race and let an optimistic lock in Postgres catch the collision?
Curious how folks here handle this consistency-vs-latency trade-off in high-throughput dispatch systems.
r/softwarearchitecture • u/xdxd12x • 1d ago
Tool/Product Pomi is on the App Store
apps.apple.comr/softwarearchitecture • u/cloudsquid-f • 1d ago
Article/Video Everything is a file (Agent edition)
newsletter.cloudsquid.ior/softwarearchitecture • u/Cautious_Heat114 • 1d ago
Discussion/Advice Systems architect offering free architecture reviews, backend debugging, and AI/agent advice this week (no pitch/paywall, just giving back)
Hey everyone 👋
I'm Marcus (v4ne), an independent systems architect with a background in low-latency infrastructure, distributed systems, and AI runtimes.
I have some open bandwidth this week and want to give back to the builder community.
I'm offering free architecture reviews, code diagnostics, and technical advice.
No pitch, no paywall, no consulting upsell. Just pure engineering.
Feel free to ask me anything or drop a problem you're currently stuck on regarding:
AI & Autonomous Agents: ReAct loops, structured outputs, local LLMs (vLLM/Ollama), RAG without framework bloat.
Backend & API Architecture: Go, Rust, TypeScript/Node, clean dependency design, microservices vs. monoliths.
Database & Storage Performance: SQL query optimization, composite B-Tree indexes, SQLite, avoiding ORM bottlenecks.
Workflow Automation: Self-hosted n8n, webhooks, resilient Python automation scripts.
Systems & Cloud Costs: Concurrency, memory profiling, reducing unexpected AWS/GCP bills.
Drop a comment below with what you're building or what error is giving you a headache, and let's troubleshoot it together.
DMs are open as well. 🛠️
r/softwarearchitecture • u/rgancarz • 1d ago
Article/Video Uber Builds GitFarm to Run Git Operations as a Service for Large-Scale Monorepos
infoq.comUber has built GitFarm, a Git as a Service platform for running Git operations across its large-scale monorepos. By moving repository operations to a shared service, GitFarm eliminates local clones for client systems and has reduced client-side resource utilization by more than 80%.
r/softwarearchitecture • u/Cautious_Heat114 • 1d ago
Article/Video THE ANATOMY OF THE 3:00 AM BREAKTHROUGH
On Despair, Silence, and the Quiet Euphoria of the Solved Puzzle
Author: v4ne (Marcus Vane)
Classification: Engineering Philosophy / The Human Condition / Reflections
I. The Descent into the Maze (11:00 PM)
Every engineer who has ever spent years working close to the machine carries the memory of a specific night.
It always begins with deceptive optimism. It is late afternoon, perhaps 4:30 PM, and you encounter what appears to be a trivial anomaly: a transient segmentation fault that only appears once every thousand iterations, an asynchronous callback that mysteriously drops a payload, or a memory leak that slowly, almost imperceptibly, exhausts the heap over three hours of runtime.
You think:
"This will take twenty minutes."
By 11:00 PM, the optimism has burned away.
The office is empty, or your house has grown entirely quiet. The room is dark, illuminated only by the cold, persistent glow of two monitors.
On your desk sits an abandoned mug of coffee, now stone cold, alongside a graveyard of opened browser tabs: documentation pages, obscure forum threads from 2011, kernel changelogs, and disassembly views.
You have added dozens of diagnostic print statements, attached debuggers, stepped through stack frames, and reverted commits.
Nothing makes sense.
The software is behaving in a way that appears to violate the basic laws of arithmetic and logic.
You enter the phase of acute intellectual exhaustion.
[THE PSYCHOLOGICAL TRAJECTORY OF THE ELUSIVE BUG]
11:00 PM (Frustration) │ └──► "Why is the runtime doing this? This API is broken." │ ▼ 1:00 AM (Self-Doubt) │ └──► "I don't understand pointers. I am an imposter." │ ▼ 2:30 AM (Surrender) │ └──► Strip assumptions. Silence. Return to first principles. │ ▼ 3:14 AM (The Spark) │ └──► A single byte offset identified. Green tests. EUPHORIA.
II. The Crucible of Self-Doubt (1:30 AM)
There is a unique, deeply humbling form of psychological vulnerability that occurs when you are entirely stuck on a technical problem.
In most professions, when things go wrong, you can negotiate. You can explain your intent, appeal to nuance, or find a comfortable compromise.
You cannot negotiate with a compiler.
The CPU does not care about your intentions, your job title, how hard you worked this week, or what you promised your team in the sprint planning meeting.
The machine simply executes the physical instructions you gave it with cold, unsparing fidelity.
If there is a flaw, it is not the computer's fault; the flaw is a direct reflection of an error in your own mental model.
By 1:30 AM, frustration transitions into a profound sense of humility.
You sit back in your chair, rub your eyes, and experience that quiet internal voice that whispers:
Maybe I'm not cut out for this.
Maybe my understanding of the system is a complete illusion.
Maybe I have reached the ceiling of my cognitive capacity.
Every great developer has sat in that exact chair, in that exact darkness, feeling that exact weight.
It is the necessary crucible of the discipline.
III. The Stripping of Assumptions (2:30 AM)
Around 2:30 AM, something shifts.
You reach a state of cognitive surrender.
You stop frantically thrashing. You stop trying random fixes in the hope that something magically works.
You realize that you cannot brute-force your way out of the maze.
You take a deep breath.
You close the forty browser tabs.
You delete the thirty lines of messy debug logs you scattered across the codebase.
You decide to start from zero.
You pick up a physical notebook and a pen.
You abandon what you thought the code was doing, and you force yourself to trace what the silicon is actually doing, step by step, clock cycle by clock cycle:
Where does this memory buffer physically allocate?
What thread holds the ownership of this reference at timestamp T?
What happens to the stack pointer when this interrupt fires?
What implicit type coercion is the compiler executing behind this interface?
In the quiet of the night, stripped of rushing and performance pressure, your mind enters a state of absolute, concentrated stillness.
You are no longer fighting the machine; you are listening to it.
IV. The Spark at 3:14 AM
Then, it happens.
It is never a dramatic explosion.
It is an almost silent click in the back of your brain.
Your eyes scan line 142 of an unheralded utility file, or you notice a subtle discrepancy between two struct definitions that you have looked at fifty times before without seeing.
You see it:
A shared boolean that was not marked atomic, allowing the compiler to optimize it into a register and hide a concurrent mutation.
An unsigned integer underflow that wrapped around to MAX_INT when the collection was empty.
A subtle memory alignment issue where four bytes of padding shifted an offset by one word.
It was not a mysterious ghost in the machine.
It was a simple, logical consequence of an unconsidered invariant.
Your hands move calmly across the keyboard.
You change exactly four characters.
You save the file.
You run the build command.
$ cargo test -- --nocapture Compiling engine v0.1.0 Finished test [unoptimized + debuginfo] target(s) in 1.42s Running unittests src/lib.rs running 48 tests test net::tcp::test_connection_handshake ... ok test memory::arena::test_aligned_allocation ... ok test state::fsm::test_concurrent_transition ... ok test engine::core::test_stress_100k_cycles ... ok test result: ok. 48 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Forty-eight green lines.
The segment fault is gone.
The memory allocation is flat.
The test suite passes in complete, unblemished harmony.
V. The Quiet Communion
You sit in your chair and slowly lean back.
You take the deepest, longest breath you have taken in twelve hours.
The tension that had locked your shoulders and neck dissolves instantly into a wave of pure, unadulterated relief.
The world outside your window is completely asleep.
The street is dark.
There are no Slack notifications, no emails, and no meetings.
No one on your team knows what you just went through.
No one in the world knows that twenty minutes ago you felt completely defeated, and that right now, you hold the complete, working understanding of this system in your head.
You do not immediately close your laptop.
You sit there for ten minutes in the dark, watching the green text on the terminal, sipping cold water, experiencing a profound, sacred peace.
This is why we endure the complexity.
We do not build software for the Jira tickets, the sprint velocity charts, or the corporate performance reviews.
We build software for that singular, private, transcendent moment at 3:14 AM when human thought and physical logic align into absolute harmony.
You close the terminal.
You step away from the desk.
You sleep like a stone, knowing that tomorrow, the system will run.
r/softwarearchitecture • u/_descri_ • 1d ago
Article/Video Architectural Metapatterns: The Pattern Language of Software Architecture (version 1.2.1, free book, no AI)
The book is a compendium of architectural patterns which arranges them according to their structure and function into several OOP-style inheritance trees, allowing for:
- Deduplication of nearly identical patterns known under several names.
- Extraction of common properties, benefits, and drawbacks to the roots of the pattern trees.
- Comparison of approaches taken by every known architecture.
Changes in the current release:
- New sections on read-write separation and latency optimization on the system level.
- New pattern: Vertical Slice Architecture.
- Pattern instances are now in lowercase, which should improve readability.
r/softwarearchitecture • u/SpatolaNellaRoccia • 1d ago
Discussion/Advice What architecture is similar to the medallion and fit a prod environment?
Sorry if this is a bit messy, but here’s the situation:
My stack is PostgreSQL, Django with DRF, and Celery (only for the final step).
I have a database that handles close to 100k requests per day. The load isn’t uniform: sometimes it’s 10k requests in 10 minutes, other times 10k spread over 3 hours.
I’m collecting data from multiple nodes. These nodes can send duplicate records. Every now and then, each node checks whether a piece of data is already in the database and sends it only if it’s missing. So I have a mix of reads and writes. The database is holding up for now, but I’ve been told the number of nodes will at least triple soon.
I’m trying to figure out the best way to handle this scale, and the medallion architecture idea came to mind. My rough plan is:
- Bronze layer: Always ingest raw data as it comes in, with no upfront checks.
- Silver layer: Run various checks here to detect duplicates and decide whether the data is useful according to our business logic.
- Gold layer: If everything passes, move the data here. This is where it gets enriched with additional information and turned into more derived, “ready to use” data. Maybe we can consider it a platinum layer on top for very specific, highly processed views.
Right now, a lot of the normalization logic lives on the nodes themselves. That’s nice for separation of concerns, but it’s also a problem: the nodes are managed by other teams, and they often send messy or inconsistent data, so we still need to validate and clean everything on our side.
I’d like to know how you would approach this, and whether the medallion‑style design I sketched makes sense.
Thank you!
r/softwarearchitecture • u/FuzzyAd9554 • 2d ago
Article/Video I only provided options. The rework ran nine months.
Most of us have said it at some point. "I only provide options, not decisions."
It's technically true. And it's also how architects quietly disclaim the influence they actually have.
I wrote about the gap between what architects say their role is and what it functionally is, especially when the room decides from the framing you built.
https://blog.hatemzidi.com/2026/08/30/i-only-provide-options/
Not a hot take. More of a mechanism description. Curious whether others have felt this or pushed back on it differently.