Assume each transaction is 1 KB, and we audit 100k transactions in one audit. Total size = 1 KB * 100k = 100 MB / audit.
Assume we run scheduled audit once a day, and may run ad-hoc audits.
Assume on average, audit of one transaction performs 20 different checks, and they totally take 1 millisec to complete. Total time = 1 millisec * 100k = 100 seconds to complete one audit.
It's easily to fit the job in one machine.
Assume we keep one year of auditing history, and the auditing result log size is similar compared to the original transactions. 100 MB * 365 = 36.5 GB. Assume ad-hoc audits are less than scheduled audit, we will need, say 50 GB total. The result can also be easily fit into one disk storage.
We don't expose APIs externally. Internally, an audit requires the following inputs:
We store audit results into database. Result data size is small, and checks performed are well predefined. SQL database may be used.
Database: audits
Table: rules. This to store what rules of checks we perform in audits.
Schema:
Table: rules_history. This to store the history of all changes to the rules table. Schema is similar to the rules table.
Table: results.
Schema:
Table: schedules.
Schema:
Table: schedules_history. Schema similar to schedules table.
See diagram
Scheduled audit:
Ad-hoc audit:
similar to scheduled audit, but user provides audit rules and which transactions need to be audited.
As mentioned earlier, the audit machine may fail, the result database may fail. See previous for mitigations.
In addition, the database or storage which contains the transactions to be audited may also fail. We need backups for such as well.
If the audit will be performed on a much larger scale, we should think of distributing different batches to different machines, and potentially store results into different database shards. This will result in a distributed system.