One of the things I love most about SaaS is it’s the “as a Service” that really matters, not the Software.
Salesforce, those arch marketeers, really nailed it in the early 00’s with their cheesy logo and techie-baiting NO SOFTWARE slogan; as far as the users and customers were concerned, there was no software, just a service.
But, of course, if you’re part of the team that delivers a SaaS product you know there is software, often loads of it, it’s just that the users and the customers can’t see it and don’t care about. And this is an incredibly freeing dynamic for that delivery team.
If you ship desktop office software and you want it to offer a new feature - perhaps the tracking of expenses via the processing of scanned receipts - then the only way to offer that is to write software. We need software to handle the image files, do the image processing of those files, store the successfully processed expense data, inform the user of the receipts the system failed to process, provide a UI for reviewing the successes and failures …
And you’d better do a thorough job of user research and UX design because if you ship something that doesn’t really work for the user it might be another year before their corporate IT team upgrade them to the next version of your software — if they’re still a customer at that point
So what if we were adding expense receipt processing to an existing SaaS product? How much actual software do we need to write?
How would it look if we try to deliver the service by writing as little software as possible?
We need to get the receipts from the user but email is a pretty effective file transfer service, perhaps we don’t write any software for that but publish an email address instead and have someone monitor the inbox?
We need to image process the sent files and maybe this is something we can use an existing AI service for. Or maybe we could just look at them ourselves. Either way, the handling of inbound receipt files and the turning of that into expense data could be orchestrated by a human.
Anything we fail to process could just be emailed back to the user and a human could certainly do a better job of explaining the problem than a computer could (“the last entry and the total amount is smudged but I think it’s either $100 or $108” vs. “can’t parse due to potential data corruption”).
Successfully processed receipt data needs to live somewhere and assuming you don’t want loads of spreadsheets sitting around, maybe we need a database of some kind. There’s some software required here. We also need to be able to get the data into the database so we need some kind of data entry interface but we can train the humans handling the files to use an off-the-shelf data admin tool. They’re not pretty but they certainly do the job.
The user needs to be able to review their successfully processed receipts and whilst we could just email them back what’s stored against them in the database, let’s assume that they actually need to see all of their expense data instantly on demand. So some software is required to let the user list all the entires in their expense database.
By thinking about the service in an software-phobic way we’ve managed to reduce something that requires a large number of individual features and the integration of some fairly specialist image processing software to an email address, some human effort and a database with a single feature to list the entries; hardly the most complex of implementations.
“But that will never work. It will be slow, error prone and expensive. It will never scale.”
Except that it will actually work.
It may be slow, error prone and expensive, but it will actually process scanned receipts and allow the customer to track expense data. As far as the user is concerned they enter some receipts into the system and get to review processed expense data once they’re processed.
It will also allow you to do some really important things.
It will allow you to assess whether customers really want this service from you at all. Maybe all those customers who told you they wanted you to do this actually decide it’s cheaper to pay some office junior overtime than paying you.
It will help you get the service out the door quickly. If the service is really valuable most customers would rather get that value now (albeit with some rough edges) than wait around for the perfect service to come some undetermined time in the future.
It will help you refine the service before you commit too much money to building the wrong thing. Maybe you’ll find that the customers who are prepared to pay you don’t really care all that much about the processing of the receipts but they do care about cost control. They’re happy to enter the expense data directly but what they really value is a series of notifications and workflows around the build up of expenses.
I think of this as Service Driven Design. Think about the service you want to deliver and find the quickest and simplest way to deliver that to your customers. Work with them to refine the service and resist converting those refinements into code as long as you can.
Of course not every type of service is as amenable to software-phobic implementations as the processing of receipts. And if we’d chosen not to implement the UI for reviewing processed expenses it may be that the service was so bad users simply wouldn’t want to even try it. There is real skill and experience in designing the minimal level of software support for a successful early-stage service. But it can be done.
And let’s say you manage to pull it off and deliver a service that is roughly what customers want. Now you have the slow, error prone and expensive problem.
You’re now faced with the pain caused by all those decisions you made not to develop software.
I think of this as Pain Driven Development. Create some problems for yourselves and then use your implementation skills to solve these problems. Automate the pain away. If the service design is right you will have some breathing space to do so, if the service design is wrong, work on that first.
This can be quite scary the first time you do it. Myself and most product developers I know suffer from ‘techie guilt’: if something I’ve built isn’t perfect for everyone I’ve somehow let the side down by allowing it out the door in its imperfect state. This can be exacerbated if the some of the users of the early service are less than complementary. One time I used this approach I had 99 people telling me how great it was to be able to do what the service allowed them to do and 1 person telling me it was shit and how could any professional person deliver what I’d delivered? Did I sleep easy on the grateful praise of the 99? No I stayed up all night fretting on the dissatisfaction of the one.
Nevertheless, despite the one unhappy user (who, by the way, still used the service whilst moaning about it constantly) we launched a successful service and within a few weeks we’d implemented away all the most significant pain points, some of which we’d anticipated before launch, many of which were a surprise to us.
Don’t let techie guilt deter you.
Because if there’s something delivery teams should feel guilty about it’s spending a load of money to deliver something users and customers don’t want.
Lead with the service and let the software implementation be guided by what you learn by doing so.
This isn’t a new idea. My approach to delivering software has long been rooted in the eXtreme Programming concept of YAGNI; You Ain’t Gonna Need It. More recently Customer Development and Lean Startup have refined the ideas of working with customers to figure out what they want by launching as-simple-as-possible solutions for customers and users to get value from and provide feedback on.
Software Engineering and Product Development are littered with xDD practices and methods. I’m not suggesting SDD/PDD be added to those; they’re just a lighthearted way of encapsulating a serious point which is to lead with the service and let the software implementation be guided by the value and feedback you generate by doing so.