MicroNotes VIII: Designing Microservices for the Edge — Lessons from Fish Farming
Notes from Sam Newman’s Microservices Workshop — Bangkok 2025
MicroNotes VIII: Designing Microservices for the Edge — Lessons from Fish Farming
Notes from Sam Newman’s Microservices Workshop — Bangkok 2025
Coordination is sorted. But what if your microservices aren’t sitting in a nice data center with perfect connectivity? What if they’re out in the real world where the internet cuts out, devices are tiny, and everything is working against you?
We’ll explores a real-world scenario: designing a microservice architecture for fish farming. It’s not about fish farming. It’s about the architectural challenges that come up when you’re dealing with IoT devices, edge computing, and unreliable connectivity.
The Scenario: Fish Farming Monitoring
Imagine a company called Livestock Insights (the company’s headquarters in Scotland, actually operating all over the world). They provide software and hardware for fish farmers. Their main product, Fishy Watch, monitors the health of fish and water conditions.
Sam met someone ten years ago who worked in fish farming in Norway. They had software ten years ago that could identify sea lice on farmed salmon and would then use carefully laser-based technology to shoot the parasites off the fish. In this exercise, they’re not doing lasers because that feels far-fetched, but that technology exists now.

The setup:
- Fish farms have multiple enclosures
- Each enclosure has hardware devices monitoring:
- Water quality (pH, salinity, oxygen levels, particulates)
- Weather conditions
- Underwater cameras (image recognition for fish size, parasite detection)
- Customers might have multiple fish farms in different locations
Interesting features:
- They have a feature with that camera. It’s an early feature where they can do face recognition of fish so they can track the life of individual fish. Sam’s not sure if it’s a bit of fun, but it gives them a rough idea of how big the fish are, if they’re looking healthy, and so on.
- They’re doing things like mussel farming, for example. They don’t mean to harvest the mussels. Mussel farming is easy. Throw a rope in the water.
Requirements:
- Dashboards to view and analyze data
- Alerts when thresholds are reached (e.g., oxygen levels dropping)
- Long-term data storage for trends
- Real-time monitoring (need to know quickly when water quality is problematic)
- Support for different types of fish
Constraints:
- Fish farming happens on ships or coasts, not in your living room
- Patchy cell signal in these locations
- Devices are low-powered (less powerful than a Raspberry Pi)
- Hardware devices already exist (you’re designing the software architecture
Future considerations:
- They’re thinking about going more generic and doing something similar for cattle and dairy herds. There are some things they care about. Water levels are important. If you’re monitoring cattle, you need to know water levels. But there are some generic ideas there.
- They’re thinking about using it for monitoring aquariums as well.
The Core Challenge: Unreliable Connectivity
The biggest challenge here is connectivity. You can’t assume devices always have a connection to the cloud. Cell signal is patchy. Networks go down.
Getting data from devices back to your system requires a different approach. You need patterns that handle intermittent connections.
Common Solution: Store and Forward
Most teams working on this scenario came up with a similar solution:
The pattern:
- Devices send data to a local broker/queue at the farm
- Local broker stores the data
- When connectivity is available, forward data to cloud broker
- Cloud services consume from cloud broker
Why this works:
- If connectivity is lost, data is stored locally
- When connectivity returns, data is forwarded
- Devices don’t need to know about connectivity issues
- You can prioritize what gets sent first
Two types of data:
- Time-sensitive: alerts, critical water quality issues
- Less time-sensitive: regular monitoring data, trends
Once you’ve got the store-and-forward pattern, the next question is:
what protocol should devices use to communicate?
Communication Protocols: MQTT for IoT
For IoT devices, MQTT is often the right choice.

Why MQTT?
- Lightweight messaging protocol designed for IoT
- Works well on low-powered devices
- Can do both event-driven and request-response
- Designed for devices that aren’t very powerful
MQTT broker bridging: You can bridge MQTT brokers. A broker at the farm connects devices locally, then forwards to a cloud-based broker when possible.
Common pattern in industrial IoT.
Then there’s another question: where should processing happen?
Local Processing vs Cloud Processing
The question is where alerting should happen.
Option 1: Cloud-based alerting
- Alerts processed in the cloud
- Problem: if connectivity is lost, alerts don’t work
- Simpler architecture
Option 2: Local alerting
- Alerts processed at the farm
- Works even if connectivity is lost
- More complex
Tradeoff: local intelligence = resilience but added complexity.
Mesh Networks: Handling Device Communication
Some teams considered mesh networks (like Zigbee).

The idea: devices form a peer-to-peer mesh network. If one device can reach the gateway, others can route through it.
Considerations:
- Distance between enclosures
- Distance from the farm to other locations
- Different signals travel different distances
Not all data is equally important.
Data Prioritization
You might want to:
- Prioritize critical alerts
- Send time-sensitive data first
- Batch less important data
Handled in the publisher or with queue priorities.
The Architecture Pattern
Common elements across teams:
- Edge layer: devices in enclosures
- Farm gateway: local broker/queue, handles store and forward
- Cloud layer: cloud broker, services, dashboards
Communication flow:
- Devices → Local broker (MQTT)
- Local broker → Cloud broker (when connected)
- Cloud broker → Services
- Services → Dashboards, alerts, storage
Key Architectural Decisions
1. Store and forward at the edge Don’t assume connectivity. Have local storage that forwards when possible.
2. Use appropriate protocols MQTT for IoT devices. HTTP/REST for cloud. Different protocols for different needs.
3. Consider data loss tolerance Some data can be lost, some can’t. Make tradeoffs.
4. Separate concerns Edge = data collection + local storage. Cloud = processing + analytics.
5. Handle failures gracefully Local broker filling up, devices crashing, days of downtime — plan for it.
Lessons for Microservices at the Edge
1. Connectivity is not guaranteed Intermittent connectivity is the norm.
2. Devices have constraints Choose protocols and patterns that respect these.
3. Not all data is equal Critical alerts > trend data.
4. Local processing has tradeoffs Resilience vs complexity.
5. Protocols matter MQTT for devices, HTTP/gRPC for cloud.
6. Broker bridging is useful Solid pattern for edge → cloud.
Beyond Fish Farming
Applies to:
- Industrial IoT
- Remote monitoring
- Edge computing
- Any situation with unreliable connectivity
Not about fish. It’s about real-world microservices with real-world constraints.
What to Remember
When your microservices need to work at the edge (like IoT devices, remote locations, or places with unreliable connectivity), the rules change. Here’s what matters:
Don’t assume connectivity. Devices might be offline for hours or days. You need store-and-forward patterns. Devices send data to a local broker or queue. When connectivity is available, that data gets forwarded to the cloud. If connectivity is lost, data is stored locally until it can be sent.
Use appropriate protocols. MQTT is designed for IoT devices. It’s lightweight, works on low-powered devices, and can handle both event-driven and request-response patterns. For cloud services, you might use HTTP or gRPC. Different protocols for different needs.
Prioritize data. Not all data is equally important. Critical alerts need to get through quickly. Regular monitoring data can wait. You might use different queues or priorities for different types of data.
Consider local processing. If you want alerting to work when connectivity is lost, you need intelligence at the edge. That means more complexity, but also more resilience. It’s a tradeoff.
Design for failure. Think through scenarios like connectivity being down for days, local storage filling up, or devices crashing.
The fish farming scenario isn’t really about fish. It’s about designing microservices that work in the real world, where connectivity is unreliable, devices are constrained, and you need to handle failure gracefully. These patterns apply wherever you have edge devices, IoT, or unreliable connectivity. The principles are universal.
“The edge isn’t a constraint. It’s a reality.”
Design for it, and your system will work everywhere.
***All Notes
***I: What Are Microservices? II: Forget Service Size — Focus on What Your Team Can Manage III: Microservices Aren’t About Technology — They’re About Team Autonomy IV: Nobody Cares About Your Microservices — Only the Outcome V: Information Hiding — The Discipline That Makes Microservices Work VI: Request-Response vs Event-Driven — Choosing How Services Talk VII: Distributed Transactions Are Sad — Use Sagas Instead VIII: Designing Microservices for the Edge — Lessons from Fish Farming IX: Testing Microservices — Beyond the Test Pyramid X: Migrating to Microservices — Changing the Wheels While the Car Is Moving XI: Domain-Driven Design — Speaking the Same Language XII: Breaking Apart Databases — When Data Becomes the Problem XIII: Resiliency, Observability, and the Reality of Distributed Systems
메타데이터
- post_id
- 96dee74b2ae7
- slug
- micronotes-viii-designing-microservices-for-the-edge-lessons-from-fish-farming-96dee74b2ae7
- url
- https://medium.com/@vortj/micronotes-viii-designing-microservices-for-the-edge-lessons-from-fish-farming-96dee74b2ae7
- canonical_url
- https://medium.com/@vortj/micronotes-viii-designing-microservices-for-the-edge-lessons-from-fish-farming-96dee74b2ae7
- author_url
- https://medium.com/@vortj
- status
- ok
- fetched_at
- 2026-06-12 18:14:10