What Is Code Audit And How to Conduct It: Evaluation Criteria

Writing code is just like solving a math problem: there’re many multiple ways you can do it, but there’s only one correct result. To make sure the solution you or another developer have chosen is correct, you can carry out a code audit. We do it as a service, but you can make it yourself. This article gives insights on how to do that and what to pay attention to.

What is code auditing

Code audit is a process of examining and assessing the quality of code. It helps identify potential issues in various aspects, understand the state of the written code, its reliability and weaknesses, prevent potential problems. The result of an audit is a detailed report that specifies the state of code categories, with explanations and examples.

Evaluation criteria:

At Fora Soft, we conduct code audits based on 8 key criteria:

  1. Code Formatting — code organization and formatting
  2. Best Practices — adherence to modern standards
  3. Maintainability — ease of maintenance
  4. Performance — code efficiency and speed
  5. Architecture — quality of the overall design
  6. Documentation — quality of accompanying documentation
  7. Safety — code security
  8. Efficiency — resource optimization

Now, let’s go into each criterion in detail.

Code Formatting

This refers to how the code is written. Each programming language has its own community-accepted standards, usually multiple standards for each language. The formatting and the code writing style in a project should be consistent throughout all its parts. When evaluating formatting, we check the indentation, spacing, line breaks, and overall module structure. When evaluating style, we focus on how variables, methods, classes, and files are named and written.

Why is consistent formatting important?

Inconsistent code formatting can lead to difficulties in reading and understanding the code, affecting the speed of onboarding new developers to the project. Additional hours mean additional budget expenses.

Code formatting: bad example
Code formatting: bad example
Code formatting: good example
Code formatting: good example

Best Practices

In this criterion, we check if the code adheres to modern software development principles. For example, we assess whether the code follows the single responsibility principle, where each module or class is responsible for a specific task or functionality. We also evaluate how effectively the code handles errors and logs them. Another important aspect is how the specific features of the programming language are utilized in the project.

Why is this important?

Meeting this criterion ensures high-quality code and system. Otherwise, there is a risk of decreased performance, difficulties in maintenance, and implementing new functionalities into the system. Security vulnerabilities may arise, and the scalability of the project may be limited.

Architecture: bad example
Code architecture: good example. Each module is only responsible for 1 functionality


We assess how maintainable the code is, meaning whether its writing adheres to general rules that are language-independent.

Why is this important?

Software often requires constant changes, bug fixes, and additions of new features in response to evolving business or user requirements. Proper use of loops, conditions, absence of duplicated code segments, universality of written classes and functions, and their scalability make the task much easier. Otherwise, the code becomes harder to understand, more fragile, and prone to errors. Making changes or fixes will then require more time, which translates to increased expenses.


In this category, we evaluate the modules, their cohesion, and configurability. We assess how well the code and the entire project are divided into modules or components. A good architecture should be modular, with weak coupling between modules, which simplifies system maintenance and expansion.

Why is it important?

If the code architecture is unclear, complex, and unstructured, it can hinder the process of maintaining and developing the system. Developers will face difficulties in understanding the functionality and logic of the code, as well as making changes. 

Costs of fixing and modifying. Incorrect architecture may require significant changes and modifications to the code to fix issues or add new functionality. This increases development costs, time to market, and project management complexity.


We check the quality, relevance, and presence of documentation. Documentation helps clients and future developers better understand the code and its functionality. Good documentation simplifies system maintenance, development, and integration. It usually includes:

A readme file that briefly describes the project’s essence, explains how to install and use the system, etc. It is important to include diagrams that explain the workings of complex modules.

Why is it important?

The absence of documentation poses a risk of knowledge loss, especially if there have been changes or reassignments within the development team. This hinders the understanding of the system’s operation and can lead to dependence on a limited circle of employees familiar with the code.


We check the security of the code and identify vulnerabilities. Specifically:

Input data vulnerabilities. We check how user input data is handled, whether the system properly filters, validates, and escapes user input. We check for vulnerabilities such as SQL injections or script injections.

Authentication and authorization. We assess how authentication (verification of authenticity) and authorization (access control) mechanisms are implemented in the code. We check if secure password storage methods are used and if there are mechanisms to prevent password guessing or session ID guessing attacks.

Encryption and data protection. We check that confidential data (passwords, personal user information) is stored in encrypted form. We ensure that secure encryption protocols are used when transmitting data over the network.

Why is it important?

Neglecting code security increases the risk of:

  • Leakage of confidential user data or violation of their confidentiality.
  • System hacking or injection of malicious code. Violation of data integrity.
  • Loss of access to the system or service.
  • Financial losses or legal issues.
  • Damage to reputation and user trust.


In this aspect, we examine how effectively the code utilizes system resources, its performance, and algorithm optimization. We consider factors such as execution time, whether it justifies its size, memory leaks, caching (for repeated requests), and the use of appropriate data structures and algorithms.

Why is it important?

Potential risks of not meeting this criterion may include:

  • Low performance and long operation times.
  • Excessive resource usage (memory, processor time, and disk space).
  • Limitations in system scalability.
  • Instability and unpredictable behavior of the code when handling large volumes of data or high loads.
  • Deterioration of user experience and user dissatisfaction.


Code audit is not an easy task for you have to consider many parameters at once. However, it’s a necessary thing to do to make sure you’re not wasting time or money. And if you’d like some help with it, contact us. We’ll audit your product’s code, come up with solutions to how make it better, give recommendations and estimations. All for free.


Picture-in-Picture Mode On iOS: Implementation and Peculiarities

pip on ios code examples

The Picture-in-Picture (PiP) mode allows users to watch videos in a floating window on top of other windows. They can move it around the screen and place in any convenient spot. This feature enables users to keep an eye on what they are watching while interacting with other websites or applications.

We have previously covered the PiP implementation on Android with code examples. In this article, we will focus on iOS.

Picture in Picture is a must-have feature for modern multimedia applications

Here’s why:

1. Enhances multitasking. PiP allows users to simultaneously watch videos or view images in a small window while maintaining access to the main content or application interface. This enables users to multitask, e.g. watch a video while checking emails, sending messages, or browsing social media.

2. Improves user experience. The mode provides more flexible and convenient app navigation. This significantly enhances the user experience by eliminating the need to interrupt content playback or switch contexts completely.

3. Minimizes session interruptions. PiP enables users to continue watching or tracking content while performing other tasks. This helps reduce interruptions and ensures a smoother and uninterrupted workflow. For example, a user can watch a tutorial or a YouTube livestream while searching for information on the Internet or taking notes.

All these factors help retain users within the application and increase the duration of app usage sessions.

Peculiarities and difficulties of PiP on iOS

Apple envisages two scenarios for using PiP on iOS:

1. For video content playback

2. For video calls

The main issue is that for the video call scenario, prior to iOS 16 and for iPads that do not support Stage Manager, it is necessary to request special permission from Apple to access the camera in multitasking mode ( But even after waiting for several months, as in our case, Apple may still not grant these permissions.

Therefore, in our mobile video chat app, Tunnel Video Calls, we decided not to use such a scenario. Instead, we adopted the approach where a video call and its content are considered as video playback.

PiP lifecycle on iOS

The Picture-in-Picture mode is essentially the content exchange between a full-screen app and PiP content from another app. The lifecycle of this exchange can be schematically represented as follows:

transitioning to pip on ios
Stages of transitioning to the PiP mode on iOS

1. Video is playing in full-screen mode.

2. The user initiates an event that triggers the transition to PiP mode, such as pressing a specific button or minimizing the app.

3. An animation is launched to transition the video to PiP mode — the full-screen video shrinks into a thumbnail and moves to the corner of the screen.

4. The transition process completes, and the application changes its state to the background state.

Then, when it is necessary to bring the video back to full-screen mode from PiP mode, the following steps occur:

1. The app is in the background state and displays PiP.

2. An event occurs that initiates the transition from PiP to full-screen mode and stops the Picture in Picture mode – such as pressing a button or expanding the app. The app enters the foreground.

3. An animation is launched to transition the video to full-screen mode. The app enters the state of displaying the video in full-screen.

Here’s how it looks:

transitioning back from pip on ios
Steps to exit Picture in Picture mode on iOS

Implementing PiP for video playback

To enable PiP, you need to create an AVPictureInPictureController(playerLayer: AVPlayerLayer) object, and it must have a strong reference.

if AVPictureInPictureController.isPictureInPictureSupported() {
    // Create a new controller, passing the reference to the AVPlayerLayer.
    pipController = AVPictureInPictureController(playerLayer: playerLayer)
    pipController.delegate = self
    pipController.canStartPictureInPictureAutomaticallyFromInline = true

Next, you need to start playing the video content.

func publishNowPlayingMetadata() {
    nowPlayingSession.nowPlayingInfoCenter.nowPlayingInfo = nowPlayingInfo

After this, when the button is pressed or the app is minimized/expanded, the PiP will activate:

func togglePictureInPictureMode(_ sender: UIButton) {
    if pipController.isPictureInPictureActive {
    } else {

Implementing PiP for video calls

Implementing Picture in Picture mode in an iOS app for video calls using WebRTC technology is perhaps the most challenging part of the work. We would be happy to help you with it, so please reach out to us to discuss the details. Conceptually:

In this implementation, the camera will not capture the user’s image, and you will only be able to see the conversation partner.

To achieve this, you need to:

1. Create an AVPictureInPictureController object.

2. Obtain the RTCVideoFrame.

3. Retrieve and populate CMSampleBuffer based on RTCVideoFrame.

4. Pass the CMSampleBuffer and display it using AVSampleBufferDisplayLayer.

Here’s a sequence diagram illustrating the process:

sequence diagram pip on ios
PiP on iOS sequence diagram


How To Implement Screen Sharing To Your Android App [2023]. With Code Examples

Screen sharing is almost the basic function of video call platforms. Skype, WhatsApp, Telegram, Teams, Google Meet. All these systems have this feature. 

We have already explained how to implement screen sharing into a mobile iOS application. In this article we will explain how to do it on Android. With code examples. 

Also in other articles within our Android series you will learn how to make custom call notification and how we develop WebRTC systems in general.

Screen sharing implementation

You can enable screen sharing immediately when you create a new video call, in advance, before it actually starts.

However, we will take a glance at the most common case, when screen sharing starts after the call itself started.

To simplify the description of the screen sharing implementation, let’s say that we already have a ready-made application with WebRTC calls. Read more about the implementation of the WebRTC video call

Steps for implementation will be the following:

  1. Accessing screen content
  2. Creating a video track with a screen image
  3. Replacing the camera video track to the the screen video track
  4. Displaying a notification of an ongoing screen sharing

Now each one in detail: 

Accessing screen content

First we get access to capturing the screen content and device sound with Media Projection API:

val screenSharingPermissionLauncher = registerForActivityResult(
) { result ->
   // Handle request result
   val screenSharingIntent =
   if (screenSharingIntent != null) {
       // Success request

val mediaProjectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
val intent = mediaProjectionManager.createScreenCaptureIntent()

When calling for screenSharingPermissionLauncher.launch(intent), a dialog window will appear. It will tell the user that media projection will access all the information displayed on the screen.

As a result of successful access to the screen content we get screenSharingIntent

Creating a video track with a screen image

Create videoCapturer, which will capture the image from the screen:

val mediaProjectionCallback = object : MediaProjection.Callback() {
   override fun onStop() {
       // screen capture stopped
val videoCapturer = ScreenCapturerAndroid(screenSharingIntent, mediaProjectionCallback)

Then create localVideoTrack:

val surfaceTextureHelper = SurfaceTextureHelper.create("CaptureThread", eglBase.eglBaseContext)
val videoSource = peerConnectionFactory.createVideoSource(/* isScreencast = */ true)
videoCapturer.initialize(surfaceTextureHelper,context, videoSource.capturerObserver)
videoCapturer.startCapture(displayWidth, displayHeight, fps)
val localVideoTrack = peerConnectionFactory.createVideoTrack(VIDEO_TRACK_ID, videoSource)

Replacing the camera video track to the the screen video track

To replace the video track correctly, implement the renegotiation logic for both call participants. When changing local media tracks, WebRTC calls onRenegotiationNeeded. It repeats the sdp exchange process:

val peerConnectionObserver = object : PeerConnection.Observer {
   override fun onRenegotiationNeeded() {
       // Launch sdp exchange
val peerConnection = peerConnectionFactory.createPeerConnection(iceServers, peerConnectionObserver)

Now to the video track replacing. Delete the camera video track from the local media:


Stop capturing the camera video:


Add screen sharing video track:


Displaying a notification about an ongoing screenshot

At the start of the screen sharing, it’s necessary to run the Foreground Service with the notification that the demonstration has started.

Create a ScreencastService and add it to AndroidManifest.xml. Also specify the foregroundServiceType parameter:

   android:stopWithTask="true" />

Before replacing the video trach from the camera with the screen sharing video track, launch ScreencastService:

val intent = Intent(this,
ContextCompat.startForegroundService(this, intent)

Then, in ScreencastService (e.g. in onStartCommand()), call the startForeground method:

startForeground(NOTIFICATION_ID, notification)

Common issues with implementation

The app crashes on Android 10+ devices with the “Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION” error

Foreground Service ensures that the system will not “kill” the app during screen sharing. The Foreground Service notification will inform the user about the running screen sharing and will allow to quickly return to the application.

How to solve: do not forget to display the notification about the started screen sharing 🙂 

There is no replacement for the camera video track to the screen one

This might occur if the recognition logic is not implement (correctly) on one or both callers sides.

How to solve: override onRenegotiationNeeded method in PeerConnection.Observer (method name on other platforms may differ). When calling onRenegotiationNeeded, the sdp exchange process must be started.


In this article we covered the implementation of screen sharing in video call and how you can:

  • Access screen content with MediaProjection API
  • Capture screen content with ScreenCapturerAndroid
  • Create a local video track with screen image
  • Replace the camera video track with the screen video track
  • Implement Foreground Service for displaying screenshot notification

See the final result of screen sharing implementation in our secure video calling app.


How to Teach Your iOS App Recognize Tone of Voice

speech recognition with neural network on iPhone app

Learn more about neural networks and how they work in general in one of our previous materials with comics. This article is a guide to how to work with them on iOS. And in particular, how to implement speech recognition and characterize what’s recognized. With code examples.

We will explain it with an example /solution that we have developed for one of our projects. Starting with quick intro into the framework we will be using, we’ll then proceed to creating a model, training it with your app data, and analyzing results.

What framework to use: about CoreML

How to determine the phrase toxicity on iOS in real time?

  Phase 1: preparing the data for the speech classification model training

     How to tell everything is ready and works correctly?

  Phase 2: receiving the audio signal and sending it for speech recognition

  Phase 3: speech classification

    How to enhance the results accuracy?

Alternative ways to get MLModel

What framework to use: about CoreML

CML (Core Machine Learning) — is an Apple framework for implementing machine learning to an iOS app. Apple built it in 2016 as a supplement to what they had on working with matrixes and vector algebra (together building up the Accelerate framework) and computing based on the Metal graphic technology — core neural network tools.

Neural network frameworks hierarchy
Neural network frameworks hierarchy: top level uses the results from the bottom layers.

CoreML has nothing to do with neural network training. It is only able to import a ready-made, trained model and provide the developer with a user-friendly interface to work with it in the application. For example, we submit the text to the input of the ML model and get its classification at the output.

Simplified text classifier scheme
Simplified text classifier scheme

For that CoreML integrates a fully trained model, it provides a powerful flexible tool for working with neural networks. It is possible to import almost all popular neural networks:

  • BERT, GPT — for tasks with natural language, the one we speak every day,
  • neural networks for image classification, etc.

There’s just one limitation: the number of tensor components must be <= 5. That is, no more than 5 dimensions.

We should mention what a neural network model is. This is the result of neural network training that contains a weighted graph with the best combination of weights. And gives out a result at the output.

How to determine the phrase toxicity on iOS in real-time?

You can apply the algorithm below to characterizing speech in general. But to exemplify, we’ll focus on the toxicity. 

So, to determine the toxicity of a phrase, you need to divide the problem into several phases:

1. Prepare training data with toxic and non-toxic phrases;

2. Obtain a model of the neural network trained on the data set;

3. Write down the phrase;

4. Send the phrase to the SFSpeechRecognition library for voice analysis and get the phrase in text;

5. Send the text of the trained model to the classification and get the result.

To describe it with a diagram, the problem is as follows:

Speech recognition model scheme
Speech recognition model scheme

Now each phase in detail.

Phase 1: preparing the data for the speech classification model training

To get a trained model you can go two ways:

1. Develop the neural network yourself and train the model;

2. Take a ready-made model and ready-made neural network, train it on your own data set, use Python as a tool, for instance.

To simplify the process, we’ll go the second way. Apple has an excellent set of tools for this, so starting with Xcode 13, the debugging process of the model became as simple as possible.

To begin with, launch the CreateML tool (it’s already in XCode) and create a new project. Select TextClassification (Apple uses BERT) and create a project. You’ll see a window for uploading the prepared data.

On the output, the tool accepts two datasets:

  • the set for the model to complete its learning;
  • the set to compare the results to.

All the data must be in json or csv. The dataset structure should follow the template:

For json:

       "text": "The movie was fantastic!",
       "label": "positive"
   }, {
       "text": "Very boring. Fell asleep.",
       "label": "negative"
   }, {
       "text": "It was just OK.",
       "label": "neutral"
   } ...

For csv:

"The movie was fantastic!",positive
"Very boring. Fell asleep.",negative
"It was just OK.",neutral

The data is ready, now you can upload and start training the model:

Starting a new training
Starting a new training

How to tell everything is ready and works correctly?

To evaluate the results, there are reports for each learning project:

Training results report
Training results report

Precision — how well the model identifies the target (in our case the target is the phrase to characterize), with with no false-alarm.

Recall — how correctly the model identifies the target. 

F1 score — an indicator that combines the accuracy and complexity of the algorithm. Here’s how you calculate it:

F1 score formula
F1 score formula

The higher the Precision and Recall, the better. However, in reality, it is impossible to reach the maximum of both indicators at the same time.

All you have left to do is to export the received model, in *.mlmodel.

Phase 2: receiving the audio signal and sending it for speech recognition

On iOS it is the Speech framework translates voice into text. There’s a trained model in it already. Since our main task is to translate speech to text in real time, the first thing to do is to get the samples of the AVAudioPCMBuffer audio signal and them to the recognizer.

class AudioRecordService {
   private var audioEngine: AVAudioEngine?
   func start() {
            do {
                audioEngine = try configureAudioEngine()
            } catch {
    private func configureAudioEngine() throws -> AVAudioEngine {
        let audioEngine = AVAudioEngine()
        let inputNode = audioEngine.inputNode
        let recordingFormat = inputNode.outputFormat(forBus: 0)
        inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { [weak self] buffer, _ in
        try audioEngine.start()
        return audioEngine

Set a zero-bus branch and the samples will arrive as soon as the audio frame number is 1024. By the way, a AVAudioNode object can potentially have several input and output buses.

Send the received buffer for speech recognition:

Create an enumeration for error processing

enum SpeechReconitionError {
    case nativeError(String)
    case creatingTaskError

Create an enumeration for recognition events

enum SpeechReconitionEvents {
    case phrase(result: String, isFinal: Bool)
    case error(SpeechReconitionError)

Create a SFSpeechRecognizer object

private var request: SFSpeechAudioBufferRecognitionRequest?
private var reconitionTask: SFSpeechRecognitionTask?
private let recognizer: SFSpeechRecognizer?
 init() {
        recognizer = SFSpeechRecognizer(locale: Locale.preferredLanguages[0])

Configure recognizer and launch the recognition task

    func configureRecognition() {
        request = SFSpeechAudioBufferRecognitionRequest()
        if #available(iOS 16.0, *) {
            request?.addsPunctuation = true
       if let supports = recognizer?.supportsOnDeviceRecognition, supports {
            request?.requiresOnDeviceRecognition = true
        request?.shouldReportPartialResults = true
        guard let request else {
  reconitionTask = recognizer?.recognitionTask(with: request, resultHandler: recognitionTaskHandler(result:error:))

The function to add audio buffers to the recognition queue

  func transcribeFromBuffer(buffer: AVAudioPCMBuffer) {

Configure the results processor

    private func recognitionTaskHandler(result: SFSpeechRecognitionResult?, error: Error?) {
        if let result = result {
            events.onNext(.phrase(result: result.bestTranscription.formattedString, isFinal: result.isFinal))
            if result.isFinal {
        if let error {
    private func eraseRecognition() {
        request = nil
        reconitionTask = nil

The recognition process will start immediately after configureRecognition(). Then transfer the resulting audio buffers to transcribeFromBuffer(buffer: AVAudioPCMBuffer). 

The recognition process takes about 0.5-1 seconds. Therefore the result comes asynchronously in the function ecognitionTaskHandler(result: SFSpeechRecognitionResult?, error: Error?). SFSpeechRecognitionResult and contains the results of recognition of the last audio buffer, as well as the results of all previous recognitions. That is, on the screen the user sees the last recognized sentence and everything that was recognized earlier. 

Also, recognition doesn’t always occur directly on the device. When offline recognition is not available, AVAudioPCMBuffer samples are sent to and processed on Apple servers. To verify and enforce the offline mode, use the following command:

 if let supports = recognizer?.supportsOnDeviceRecognition, supports {
            request?.requiresOnDeviceRecognition = true

Apple claims the on-device results are worse. But there are limits for using it online.

Recognition results comparison: server vs on-device
Recognition results comparison: server vs on-device. Source: Apple Tech Talks

Phase 3: speech classification

Note: the main rule to using neural networks for speech classification is the more context there is, the better the accuracy.

First things first, import the ML model to the project as a regular file. Next, create an instance of the model class. The file name will be the class name.

init?() {
        do {
            let config = MLModelConfiguration()
            config.computeUnits = .all
            if #available(iOS 16, *) {
                config.computeUnits = .cpuAndNeuralEngine
            mlModel = try ToxicTextClassificatorConditionalAlgoritm(configuration: MLModelConfiguration()).model
            if let mlModel {
                predicator = try NLModel(mlModel: mlModel)
        } catch {
            print("Can not initilaize ToxicTextClassificatorConditionalAlgoritm")
            return nil

NLModel — is the object you’ll further work with.

Once created, the model is ready to accept input text for classification.

List the possible outcomes of the classification.

enum PredictResult: String {
    case toxic
    case positive

Now try to get the result!

 func predictResult(phrase: String) -> PredictResult? {
        guard let predict = predicator?.predictedLabel(for: phrase),
              let result = PredictResult(rawValue: predict) else { return nil }
        return result

We analyze the phrase in real time. This means that the pieces that obtained in the second phase immediately fall into the classification. Because of this, the accuracy of the classification is inevitably lost. 

How to enhance the results accuracy?

а) If there is no punctuation, classify the text as it comes after the recognition and record the result. To do this, write a function that will accept the recognized text and flag that speech recognition is over.

Reminder: the phase will contain more words each time for SFSpeechRecognitionResult returns the recognition results of the last audio buffer recognition along the results of all previous recognitions. 

func analyze(phrase: String, isFinalResult: Bool) {
        guard let predict = predictResult(phrase: phrase) else {
            if isFinalResult, let result = predictResult {
        predictResult = predict

b) If there’s no punctuation* but you need to reduce the overhead for classification, you can only take the last N words from the sentence. However, this would greatly reduce the accuracy of the classification.

*To add automatic punctuation placement (currently only available in English):

 if #available(iOS 16.0, *) {
            request?.addsPunctuation = true

To improve accuracy and reduce computation overhead, you can use the algorithm to divide text into sentences in proportion. For example, if there are 3 sentences in the text, do 2:1 or 1:2. That is, analyze the first 2 sentences first, then 1 remaining or first 1, then 2. 

Toxicity recognition results
Toxicity recognition results

Note: It’s necessary to request access to the mic and the permission for speech recognition.

Alternative ways to get MLModel

  1. Tool set for Python CoreML tools, that allows converting models trained with other neural networks to mlmodel:
    • CoreMl tools for TensorFlow
    • CoreMl tools for PyTorch
  2. TensorFlow Lite for iOS. It allows working with models trained with TensorFlow.

You can use neural networks for a plethora of different solutions. See how we work with it when developing video surveillance systems.


Using SDK vs Custom Development . What’s Best For Your Multimedia Engagement Product?

use sdk or go for custom development

When building own multimedia and communication software there always stands a question. Shall I use a ready-made solution like an SDK or API or shall I develop my own custom component? What approach would be more beneficial in the long run? What do I need to take into account to make the right choice?

So here is an article that clears things out to help you make the decision.

What is an SDK?

First, let’s figure out clearly what we are talking about. An SDK is a set of software development tools developers can use as ready-made solutions building software for specific platforms. SDKs can include one or more APIs along with programming tools and documentation. This means that this will still require developers’ effort to assemble and integrate the component but not write it from scratch. That means less development time and money paid. In this article we will focus on SDKs that communication service providers offer. Some development teams prefer certain SDK’s because they are familiar to them, but it might not be the best choice for the platform. 

How to pick the right SDK?

Here is a set of parameters to check for each multimedia engagement SDK you consider: 

  1. API and SDK documentation — whether it is clear and easy to understand for developers. If it’s not, it will lead to a higher cost of integration for an increase in the developer time and effort.
  2. Tech stack. That is languages and frameworks used on your platform and whether there is documentation for these. Paid APIs and SDKs provide documentation for the majority of languages and frameworks. It’s not the case with free APIs.
  3. Support. How well the company provides technical support in case there are difficulties in setting up the component.
  4. Reliability. You want the provider to offer the SLA (service level agreement) is around 99.99%, meaning the system will work 99.99% of the time. 
  5. Scalability limits. Some components do not allow for a large number of concurrent users.
  6. Security. Video and text-based chat content is of a sensitive nature. For that video APIs must meet the highest data security standards. When you integrate them, you also integrate top-level compliance — something else your app developers won’t need to worry about, that saves a lot of time. Yet it mostly works for paid SDKs only.
  7. Сode license of the component. If the SDK you’re using is licensed under GPL2 / GPL3, you’ll be obliged to share the source code of your whole system available on request. That means any developer can ask for the code to your product and use it for free.
  8. Regional support — whether service providers work in the country you target. For instance, Twilio works in 50 countries, while Vonage is checked successfully for 80 countries.

Pros & Cons of SDK for multimedia and engagement features


  • It saves time for development as it provides the pre-built functionality. Otherwise you’d have to build it from scratch. This, in turn, speeds up time to market for your MVP.
  • It provides a consistent and stable development environment. So it’s easier to keep your software code up to date.
  • It facilitates the integration of new features and functionalities into applications.


  • It limits flexibility and customization options for developers. They will have to work within the constraints of the SDK. For instance, certain AR video editing SDKs won’t let you upload your own face effects. Some whiteboard SDKs don’t allow attaching video files. Or, there’re SDKs that work with sound but don’t have facilities to make a certain audio protocol setup for undistorted sound. 
  • It may not provide all the features or functionality that a developer needs for a specific application. For example, adding a formula editor to a whiteboard component. So a paid solution might still require custom development.
  • It brings extra monthly costs. If your platform grows faster than you expected you may find yourself spending more on supporting the load of users with an SDK.

How to know you need to go for custom development

Answer these 3 questions:

  1. How complex is the functionality of the component that your business requires? Do you want a simple one-on-one text chat or an entire LMS system? What particular features do you expect your product to have? Complexity of the functionality is evaluated on the planning stage, when business requirements are figured. This may vary from a simple one-on-one text chat functionality to a whiteboard component for presentations, custom participant roles or making unique setup for a clear sound quality in a collaboration tool for musicians or application of a particular codec, FPS or streaming protocol. Most engagement SDKs on the market offer basic features: voice calling, text, p2p and group video chat, or streaming. Although there are providers that offer a variety of complex features such as speech-to-text transcription, recording and cloud storage functionality and custom whiteboard components. Each of these components increases the price of the SDK on per usage dramatically.
  2. How many overall or simultaneous users should your system support? Some multimedia and engagement SDKs have limitations to the number of concurrent rooms and users of the service. There’re limits for calls, conferences, streams and chats. They usually define and limit the number of participants in a chat room or a video call, a number of concurrent watchers of a stream. If you require larger numbers then those the SDK offers you’ll have to scale it up. This takes lots of effort and requires custom development.
  3. Are you ready to overpay the monthly upkeep costs for your system?
    Let’s take an example to see the difference, as features are added.
  1. We have requirements for a simple group meeting of 5 people with video quality 480p. The meeting must run for one hour. Based on our records, the cost of handling this meeting through an SDK is ~ $1,2 per hour. With a custom component that will be $0,69 per hour. 
  2. Also, the project requires a recording feature. It increases the cost of a meeting with SDK to ~$2,4 per hour. For the custom component it’ll only make 7 cents difference — the overall cost will be $0,75 per hour.
  3. Meeting recordings often require cloud storage for multiple users access. That’s another expense item. Check out how to calculate the size of a video file.
    Based on our inputs, the meeting requires 13,72GB of storage. Now the cost of a meeting with SDK will be ~$3,04 per hour and will only cost $0,81/hour with a custom component.
  4. We can also see the difference for a speech-to-text recognition. $4,96 per hour with an SDK vs $2,25 per hour with a custom component.

    So, here is what we get for one meeting. Using an SDK is twice as expensive to upkeep. However, it’s not that bad. For 500 meetings a month it will be ~$2480 vs $1125 for our example case. This monthly overpayment will have to go on for at least 3 years to cover expenses for custom development. If you are a startup that is testing out a market hypothesis and only building an MVP, then you are not expecting big numbers just yet. And this difference in the upkeep costs will not cover the initial investment to make a custom component. Also, some SDK providers offer discounts and limited free usage for startups.

    But if the system is large and you expect, say 5000 meetings a month, the difference in the upkeep costs is dramatic. Custom development will pay off in half a year and cut down your costs. The same works for all multimedia components — voice calls, text chats, streaming, video player and others.

To sum up, the choice between custom development and using an SDK involves multiple parameters to evaluate as well as prospects for the system growth. SDKs usually are a good choice for MVPs, if communication services is not the main benefit of the platform, but rather an upgrade to the main USP.

We can help you evaluating professionally. To get a consultation, request a quote or contact our Head of Sales Vadim on Skype: vadim_prushchik


Digital Payment Solutions: How to Choose a Provider & 3 Ways to Earn

how to monetize your web platform

If you’re building a platform that involves payment processing, you’ll have to integrate a payment system into it. You need it to validate and store bank card information, process payments, and manage funds in general. 

A payment system will also let you accept payments in cryptocurrencies, including Bitcoin and Etherium. 

In the article, we talk about the online payment solutions you should choose for your digital product. And also explain how you can monetize your platform with it and how to choose the right one.

What do you need a payment processing provider for?

They process all money transactions within your product: one-time purchases, subscription charges, etc. They mainly profit by retracting a fee from each transaction. 

It’s a big headache to switch between providers as it takes a lot of time and effort. So it’s crucial to pick “the one” from the very start.

How to choose a payment service provider?

When choosing a provider, you should take into account these three parameters:

  1. Your business’ country of registration
    Every payment service provider works within a certain territory and might not be supported in some countries. For example:
    • Stripe doesn’t work with businesses in the Cayman Islands. One of our clients had to register their enterprise in the USA for that reason
    • MangoPay only works within the European economic area
    • RazorPay only works in India. So if your company is registered in India and you’d like to expand internationally, you’ll have to integrate a new payment system.
      Note: You should only consider YOUR company’s legal address. It doesn’t matter where the funds are coming from. This only defines the fee percentage. For instance, if you’re on Stripe, when your users pay with European cards, the fee is lower.
  2. Payment systems
    Payment systems are Visa, MasterCard, UnionPay, and others. There might also be some limitations considering the country that issued the card. But generally most cashless payment solution process the transactions from any Visa and MasterCard cards, in any currency.
  3. How your customers will pay you
    That’s basically how your users will pay while / for using your product. Besides the usual way of paying with a credit card, you can integrate Apple or Google Pay into your platform. The fewer users need to do to pay the better.

Stripe vs PayPal vs others: pros and cons

There’re plenty of payment service providers, each serving different needs. In the last 17 years, we have worked with many payment providers all over the globe. But now we recommend sticking with these 5 and here’s why:

  • Stripe
    Simple yet powerful. Full stop. Stripe offers a wide range of functionalities that would fit any payment requirements: subscriptions, bonuses and coupons, advanced statistics and reports, and more. It’s also known as the most developer-friendly provider. Stripe would be a great choice for enterprises from the United States and Canada, but it works well for other countries as well. See what countries Stripe works with. We in Fora Soft personally work with this provider the most.
  • PayPal
    An alternative to Stripe but works in more countries, yet a bit less modern. It works well for the basics and is easy to set up, but it lacks agileness when it comes to customization. There’re also these major drawbacks:
    • you cannot customize the checkout flow
    • it’s impossible integrate Apple Pay, Microsoft Pay, and a number of other payment methods
    • limited personalization: PayPal is simpler to set up, but it can’t be customized to fit your specific needs
    • it’s costlier than Stripe
    • no CRM
  • MangoPay
    Might be a good choice for businesses registered in Europe. The fee percentage is quite low and the payout is almost free. But you’ll have to waste a couple of hours on bureaucracy. For instance, in MangoPay a user can withdraw money to their bank account but they’ll have to use their ID or even an entire folder of docs if we’re talking businesses. Another drawback — you can’t connect MangoPay to neither Apple nor Google Pay.
  • RazorPay 
    The best option for India, works only there, with Indian rupees. RazorPay is widely used in the country as it’s a quite reliable payment service provider. The one and only drawback is that you can’t connect it to Apple Pay. Feel free to integrate Google Pay though.

Monetization types and how to implement them

The monetization type you want for your product depends on the business model you’ve picked for it: subscriptions, one-time payments, etc. Here are the most common ones:

One-time payment

Would work well with, for instance, online movie lease (like in Vodeo), online stores, or any service where users have to pay for each unit. 

For web platforms one-time payment works in 2 possible scenarios:

  1. Request user data within the platform sent it to the provider, and receive and display the response. A few nuances:
  • You’ll have to spend much time for a decent UI that will not only look good but will also display the errors correctly.
  • Users might not trust a new platform that asks for their bank details
  1. Forward users to the checkout page by a known payment service provider. You might have experienced it yourself when you push that “Pay” button and here you are on a completely different page asking for your card details.

    What’s good about it:
  • integrating checkout takes less time than developing your own page from scratch = saves you money
  • Apple and Google Pay support
  • users can manage their coupons and discounts, taxes like VAT, etc.
  • you can customize the checkout page if necessary

What your users can’t do though is save their card details for further fast purchases.

What it looks like

Stripe Checkout page
Stripe checkout page
MangoPay checkout page
MangoPay checkout page


Users pay for a certain period they have access to the platform and a certain bunch of features, depending on the plan.

There’re 2 ways to implement this monetization plan:

  • on your own, within the platform 
  • with Stripe Checkout 

Integrating it into your product is easier and quicker than developing your own. Stripe Checkout is a complex payment processing system that also works well for subscriptions. Yet, it definitely can cover all the requirements your product might have. In Stripe Checkout you can:

  1. Set the price, trial period, payment frequency
  2. Keep track of the subscription status (paid / not paid)
  3. Add Stripe Customer Portal to have your users manage their subscription and change the payment method on their own
  4. Set the scheduled payments 

Why reinvent the wheel?

paying for subscription on stripe
Paying for a subscription on Stripe
Managing your subscriptions on Stripe
Managing subscriptions on Stripe

User-to-user or Platform-to-user

Marketplaces, online workout services, and any other products where a platform “pays” to its users are usually on this monetization type.

How it works

There’re two parts to the process:

  1. Money gets into the system
  2. It gets out. Easy, right?

We all know what happens with the first step: a user enters their card details within the system or on the checkout page.

To make the second part happen you can either develop it manually or use a ready-made solution. We usually go with the latter and pick Stripe Connect.

But as a third-party solution, it has limitations. When making a transaction both your platform and the user have to be registered in the same country. International transfers are only available for companies registered in the USA.

How to accept crypto payments as a business?

Many companies including Virgin Airlines, Microsoft and others accept cryptocurrency payments. But not all payment service providers are ready to process them for the lack of security.

However based on what Stripe itself and Bloomberg claim, the named platform processes payments in at least 2 cryptocurrencies: Bitcoin and Ethereum.

PayPal and Braintree work with cryptocurrencies as well. 

Final words and recommendations

We’ll be glad to come up with a specific solution picked individually for your project. Contact us to discuss your ideas.

And if you’d like to decide on your own here, you want to base your decision on 4 things:

  • your business’ country of registration
  • payment methods and systems
  • availability of cryptocurrency operations
  • monetization type

Our general recommendation for most systems would be turning for a checkout page instead of developing an own one. Going with a highly customizable solution (like Stripe, for example) will ensure you have a flawlessly working page that looks the way you need.

stripe checkput page
Stripe checkout page. Source: Stripe

The only possible drawback here is that there’ll be a provider’s logo. But that’s the price you pay for reliable solution, saved time and budget, as well as better user experience.


Top 6 Online and Offline Investment Sources for Your Software

a mobile phone with a coin getting into it

You have an idea for a product. You don’t have anything else. Where to get money for your project? Will you really get some? What if you also need business advice along the way?

This article will answer your questions.

There are three types of investment seekers

If we’re talking startups, founders seeking investment usually fall into two categories. Each has its own investment options. Let’s see which one you are.

You have a general idea of what the product is going to be but you haven’t worked through the details

It all starts with an idea. If you have it already but are still not sure about the details, look into Angel Investment.

An angel investor (they’re also called private investors, seed investors) is basically a wealthy person who can provide financial support for a small business or an entrepreneur for ownership stock in the firm. The percentage is usually up to 25% but can reach as much as 40% or more. It may be a one-time investment or continuous money infusion. 

Angels invest in the products that are just starting off and use their own money for that. So basically any rich person can become an angel investor. However, these are high-risk investments that should not exceed 10% of an angel investor’s portfolio. Meaning they can’t spend more than 10% of their net worth on the investing. 

Angel investors usually also have the industry expertise: they’ve most likely made the money they have themselves by running a business successfully. So they can also give you business advice and guidance in your entrepreneurship as well as be a one of the key participants of the decision making process if their share allows them to. 

To find an angel you don’t necessarily need an old rich aunt or Jeff Bezos as your friend 

Try these

  • Angellist — a free tool to find angel investors or even first employees for your startup. One of the first businesses to seek out angels on Angellist was Uber, in 2010.
  • Angel Investment Network — kind of a marketplace to connect startups with investors.
  • Social media — tell about your ideas on your Twitter or LinkedIn and ask your contacts to share the info. Six degrees of separation and the power of weak ties are real!

Another category is:

You have a detailed idea description and solid understanding of how it will work

For when you:

  • know exactly what you and your business need
  • you know you will grow fast and investors will see it too

Go venture!

Venture capitalists provide funding to startups and small businesses with seen long-term development potential. You can get venture capital from wealthy individual investors, investment banks, or other financial organizations. 

What’s special about VC is that it’s not necessarily money. It can be strong managerial powers or, for instance, technical expertise and skills. 

This is a quite risky type of money allocation for investors, but the prospect for above-average profits is appealing. In most cases venture investors tend to finance high-tech projects, pharma, health, or some kind of brand new idea — anything with extraordinary growth potential. 

Here is what you need to do to win investment from a VC:

1. Identify venture capital firms that invest in businesses similar to yours. You can go both ways: research into what VC funded your concurrent and competitor businesses or look into what startups particular VC invest into. Try CB Insights — it’s a highly-regarded resource that offers data on active VC firms and associated industries.

2. Make sure that the company invests in the stage of funding that you require. Some VC might be looking to fund startups with nothing but an idea and a plan, some only invest into small businesses with an MVP and strong growth potential. Most venturing organizations provide that info along with pitch requirements on their website. 

3. Investigate the firm’s previous deals. This way you can see whether the VC you’ve picked provides the exact type of investment you seek and you don’t get a management team instead of $50k. The research method is the same as in point 1, the info is quite transparent. Or try Crunchbase.

4. Prepare your pitch presentation. You need to literally sell your idea to the investors. Here’s what you should cover.

  • Your target audience
    Describe it as detailed as possible. Include the clear definition of the segment and the TA’s known peculiarities — you must demonstrate you know them well. But don’t confuse “detailed” and “narrow”. Being too specific is not always an advantage.

    You should also research into your TA. The more client-oriented you are, the better. Try out field study for that. 
  • Problem, solution, and product image. Use prototypes, designs, or demo.
  • Technology / Innovation
    You should transparently and clearly show what technology / approach / innovation you put in the base, how it will help you take over the competition, what the value is and how this exact technology / approach / innovation serves your TA’s needs.
  • Monetization model
    This is how you plan to make money with your product and how realistic it is to make money off the product.
  • Team and implementation
    With this info you should prove you’re well aware of what key roles you need to cover in your team to get to the result. Show your current opportunities and strong understanding of the resources it requires.
  • How realistic it is to enter the market
    Explain why you feel your strategy matches the product goals and showcase how well you understand the steps you need to take to get there.

You need a mentor, a network, and support in building your business

No matter what stage you are at, business incubators might be a good solution for you.

A business incubator is an organization that helps entrepreneurs develop and succeed by providing a variety of business support tools and services such as physical space, financing, coaching, shared services, and networking connections.

Private corporations, municipalities, and public organizations such as universities and colleges frequently support business incubation programs. Their mission is to assist in the formation and growth of new firms by providing them with the required resources, including financial and technical assistance. Their office and manufacturing space is available at below-market prices, and their team provides valuable assistance and expertise in building business and marketing plans, as well as assisting in the funding of new ventures. 

Firms often stay in a business incubator for two years, during which time they sometimes share telephone, secretarial office, and production equipment expenditures with other new companies in an effort to lower operational costs.

To find an incubator 

Try the IncubatorList

The main thing to remember — look for incubators in your location and for your segment, since there are narrowly specialized incubators: for education, medicine, or even supporting women). Pay attention to what the incubator wants in return, how much it costs, if there were successful alumni, or if it’s university based.

There’re investment seeking strategies that work well for all three types

Anyone who thinks your idea is valuable enough to generate ROI (return on investment) might help. So fundraise! Here’re possible strategies:

1. Friends & Family

Don’t underestimate your close ones. They know and believe you, so this money is easy to attract. Outside investors need proof you’re serious. But another thing here — if you’re not ready to risk your own and your close ones’ money, you are probably not.

Mail chimp and Github bootstrapped themselves. See who else.

2. Crowdfunding

Make a million stranges who believe in your idea donate a dollar. How to do that:

  1. Create a campaign
  2. Make the content to engage people
  3. Set up and launch the campaign
  4. Promote campaign: e.g. on social media

Reward-based crowdfunding

It’s a form of crowdfunding when people donate money to your project and expect to get a non-monetary benefit in return: a lifetime subscription, a merch, or something else. 

Where to crowdfund reward-based:

  1. Kickstarter 

Crowdfunding platform for creative community. You might want to place your project campaign in the Technology category. There are subcategories for apps, software, and web services

Kickstarter Fees calculator
Kick starter Fees calculator

The mechanic is All or nothing: 

  • set your objective you’re seeking to crowdfund (try their template for objective estimation in .xls). If you don’t get it, all the money goes back to the backers and you get nothing.
  • define the rewards for backers: lifetime subscription, a merch we’ve mentioned before, or an event pass, etc. You can’t set equity as a reward. 
  • set the campaign period — 1 to 90 days. The most effective period proves to be 30 days. The limited time period creates urgency and motivates your community to back your project and spread the word.

Your or your business address must be located in one of the listed countries and have a bank account that meets the platform requirements. And make sure you project is none of this

If a project is successfully funded, Kickstarter collects a 5% fee from the funds collected for creators. Stripe, the payments processor, will also collect a payment processing fee (roughly 3-5%). The complete fee breakdowns are available here.

For example

kick starter project set up page with the list of categories
Kickstarter project set up page

Why is it a good idea to crowdfund on Kickstarter?

  • Can start promotion before everything’s ready by creating Pre-launch page 

Potential backers will be able to find it on Kickstarter, but you should share your pre-launch page with everyone to create excitement and attention around your project before you launch it.

  • Connect Google Analytics to the campaign.

That means you can advertise on YouTube, Google search, or the affiliated website with Google ads.

  1. Indiegogo 

Your project might fit into Tech&Innovation category with Education, Health & Fitness, Productivity subcategories. Indiegogo is mostly for tangible products, yet you still can try crowdfund your software there. Here’s what a successful software campaign is like on Indiegogo: Fluent Forever App: THINK In Any New Language

Check out the legal address and bank account requirements. 

How much can you raise?

Indiegogo offers two funding types: Flexible Funding (keep what you raise) and Fixed Funding (all-or-nothing). Learn about the differences and the pricing for each.

  1. Kisskissbankbank

It’s a French crowdfunding platform where you can finance your project with regular support of your community. Choose a monthly or quarterly recurrence and create your own subscription formulas, offer exclusive content to your contributors and finance the sustainability of your project over the long term!

Equity crowdfunding

It is a form of fundraising where you attract investors that contribute funds toward your business goals in return for a financial stake in the company. You can also allow them into the product making process depending on their investment like voting on marketing or development matters. 

Where to equity crowdfund:

Depending on where you and your business are located, you might want to try one of these platforms:






Middle East

3. Initial coin offering

ICO is a form of investment where funds are raised with cryptocurrency venture. How to get into ICO:

  1. Create your white paper — basically your idea / project description and all its aspects that might potentially catch investors’ interest. Make sure it’s well designed and is truly appealing as an investment opportunity.
  2. Publish it on any cryptocurrency stock market (e.g. Binance) and promote it.
  3. Get crypto donations (mostly in Ethereum) from backers. They’ll get project’s tokens in return.
  4. Once your project succeeds the backers can sell their tokens and profit, so in case of your success it’s a win-win situation.

Here’s top 10 most recommended platforms for ICO

Bad news: ICO involves a lot of risk taking. Good news: risks are mostly for the backers. 

Listing an ICO is not free, though. Rough estimates are in the range of $40,000 to $200,000.  


You might be seeking investment on different stages of your project development. The first one here can be building an MVP. Learn how to save money on that from our article.

And if you already have one and are seeking further stages funding, here’s what you should probably allocate budget to before you spend a penny on the actual development. 


Moodle VS Custom Development: What’s Best For Your E-learning Product

Colorful picture with devices and e-learning platforms' interface in them

You might feel on the crossroad when planning out your e-learning platform. “Do I need it to be custom developed from scratch? Or can I save up by using a ready-made solution? What risks are there?” In this article we will share our experience to answer your questions. 

Our clients ask us about Moodle so let’s use it as an example. 

What is Moodle?

As the name suggests — Modular Object-Oriented Dynamic Learning Environment Learning Management System — Moodle is a system made to manage e-learning processes. Educational institutions use it in 243 countries on 180 thousand websites with overall 312 million users.

On Moodle you can create your own courses, post news, assign tasks, make electronic journals, develop your own tests, etc. It’s an agile and free tool with lots of additional plugins that help you install any software your users might need. 

So if there’s a tool like this, why even bother developing your own e-learning platform which takes time and requires more money? Here’s a quick overview:

a table comparing two solutions
Moodle and custom development comparison table

Now in detail.

How do I know Moodle is enough for me?

There are cases when you can save up a lot of money by just building your courses in Moodle. It is when:

  • You need the platform for internal use
  • Custom UI design adapted to your branding is not a priority
  • You’re on a low budget

Moodle truly does have some benefits.

Firstly, it’s an OSS (Open Source Software). That means you can install, use, modify, and share results of your interaction with Moodle for free in compliance with GNU (General Public License).

Secondly, Moodle works on most servers that support PHP. Users can install, use, and update it on any device.

Thirdly, millions of people use Moodle to build their first products worldwide, meaning there’re always other users to help on forums, and there’s also a set of plugins for most basic functionalities: building courses, video conferencing, tests, assigning hometasks.  

Finally, there’s detailed documentation that will be very much instrumental when installing and using Moodle. And if you can’t find answers to your questions there, you can always get them on a forum. 

What issues you are probably going to have 

  1. Long time to solve tech issues
    Moodle does have detailed documentation. And if you have questions, you’ll have to get them yourself. There’s no customer support team for Moodle, which makes problem solving quite complicated.
  2. Difficulties in using plugins
    Moodle has various plugins and features that can cover almost any e-learning need. But there’s no clear instructions for how to use plugins to customize your platform. Most of the plugins are free, but some cost extra money.
  3. Need for an admin

Moodle requires an admin to work as a complete and complex system. If there’s no admin, regular users will have a really hard time performing even the most basic actions. 

Custom LMS (Learning Management System) development solves all these problems perfectly. Developing your own products gives you all the freedom. Build them the way you want, with the interface you want. And it will work perfectly fine with some maintenance. 

And in the meantime, it offers a wide range of other opportunities for building a complex yet comprehensible product. Here’s a case example from our practice.

When clients come to us with a request for an e-learning platform, they usually expect to see the following functionalities:

  • Making lessons, tests
  • Video conferencing with a digital whiteboard and shared document editing
  • Video recording
  • Classes booking
  • Homework assignments that are not solely tests
  • Publishing completed homework assignments (in .pdf, .doc(x), link, text)
  • Media library: uploading presentation, pictures of the manual pages, notes

Moodle can do most of them, but with a number of limitations. 

One of our clients came to us with a request for a video conferencing with a whiteboard. There’s a Moodle plugin for that — BigBlueButton. It has all the essential features:

  • video calling for classes
  • turning on/off the microphone
  • screen recording
  • controlling the conference as a host (block other users from joining the conference, etc.)
  • screen sharing
  • controlling video recordings
  • whiteboards
  • chat with emojis
  • custom welcome messages

To deploy all these features, it’ll take approximately 2 hours. If you also save some time for researching certain functionalities and plugins, you can extend the time spent to 8 hours. 

If you go for the custom development, it will take about 160 hours to develop the video chat, and 300 more hours for the whiteboard. 

But where do these 452 extra hours take you?

Basically it’s all about agileness. Moodle does have customization opportunities for colors, icons, etc. But when you need a white label solution made specifically for you, like what we did on BrainCert, custom development guarantees the results in the estimated time. With Moodle you never know how much time it will take to find the way to customize a feature the way you need it and if you even get there at all. That is due to lack of support. 

With all of that said, the answer to the “Moodle of custom development for your LMS-product” is:

If a platform is for internal use, doesn’t require any special features, and you’re on a low budget, then Moodle it is. But if you plan to monetize, promote, and attract many users to it, custom development is the right solution. 

Either way we’ll be happy to help you build a successful product, So feel free to contact us and discuss your ideas. We’ll come up with the solution and time + cost estimations shortly.


What Are Non-Functional Requirements And Why You Need Them? With Examples

Cool cat wearing sunglasses with the "NFR" text on each eye

There’re essentials you have to think through before you’re to develop a product if you want it to work as you expect it to or even better. These are, as we explained in our previous article, 2 types of requirements: functional and non-functional. From this article, you will learn what non-functional requirements are, and why they are as important as technical ones.

What is a Non-Functional Requirement?

A non-functional requirement, or NFR, is a requirement for the  system as a whole. It doesn’t describe user actions, system behavior, or interface. Instead, it determines WHERE the product  should be used and HOW we better design it from a technical perspective. Often NFRs are referred to as technical user stories or software quality requirements.

This is what the NFR list for a product may look like:

A table with different non-functional requirements and their specifications
A table with different non-functional requirements and their specifications
A table with different non-functional requirements and their specifications
Example of a NFR-list for a video streaming platform or a video chat

Now let’s dive deeper into the types of non-functional requirements to better understand why you even need to describe them in the first place.

Requirements to for WHERE the system should work

There are systems we expect to work everywhere: on any device, any platform, from any place. This is their technical requirement. For example, Facebook or YouTube. But they weren’t like that in the beginning. Making the system work flawlessly around the world on any device is pretty difficult and expensive. An MVP doesn’t need this to test their hypothesis and get the first users. That’s why we always ask our clients how many active users they plan to have in a few months and where they are located. This brings a lot of benefits: 

  • fits the initial system scale to the expected load — avoiding unnecessary scaling saves money;
  • saves funds for not having to maintain the load that is not expected in the near future.

Basically, when you ask yourself “Where should my system work?” and then answer your own question — this is how you articulate the non-functional requirements for localization (early adopter countries) and scalability (concurrent users, storage capacity).

Example: A Texas factory owner wants to develop a video surveillance system that can meet specific needs of the factory. NFRs to it will be:

  • Localization: USA, language — American English
  • Scalability: 1 factory, 10 security officers, up to 100 simultaneous cameras.

Most likely, this system will never have to experience the Black Friday test in Europe. However, if this is suddenly required (for example, the business grows in an unforeseen way), the factory owner will have to scale it up. 

However, it’s a big game changer if we consider the potential of scaling from the very beginning, it saves a lot of money.

Some non-functional requirements don’t even require additional timespend. It takes the whole development some time to build a functional user story and features within. A technical user story, for instance, simply comments on the date and time formats for the specified use location.

Technical user stories also determine the browser and device support. You might’ve seen a note like “For the best experience, use the latest version of Chrome”? It indicates that the developers tested the platform, obviously, on the latest version of Chrome. It may work in other versions and browsers, but the software provider themselves don’t know how exactly — they haven’t tested it. Usually this is how companies save money on testing things and features not or least used by potential users. It’s a rather simple rule: you can grow a product and add new cool features to it only when the main functionality is working perfectly. 

Requirements for HOW the system should work

1. Effective performance

How to build it so that it works well? What does “well” even mean?

Example: Let’s take the same video surveillance system. If we want it to work well, then the video quality should be high (say, Full HD). But at the same time, we want to optimize server costs so that the client doesn’t overpay. Most likely, Full HD is useless at night or when nothing happens in the picture. Then we lower the quality and boost it automatically when cameras detect motion. Or maybe leave the decision up to the user? They could set, for example, the main camera to 720p and the others to 480p. 

Depending on the specifics of the business, non-functional requirements for video quality can vary and must necessarily be specified in writing.

2. Security

Another side of “how well” is “how safe”. The system may collect or transmit sensitive (in terms of security, safety, or privacy) data. Not meeting relevant requirements can cause its owner major legal problems. In 2022 covering damage from data leaking may cost a company up to $4,35 million, according to the IBM data breach report.

Examples of security requirements: 

  • The users of the platform should be over 18 y.o.
  • The payment processing gateway must be PCI DSS compliant.
  • 1-1 calls should be HIPPA compliant.
  • User profiles and data storage should be GDPR compliant.

3. Speed

Non-functional requirements also answer the “how fast” question, in case the speed is critical. 


  • The results must load within 3 seconds.

4. Integrations

Last but not least, technical user stories define the necessary integrations into functional user stories, in case we don’t develop custom solutions.


  • If the user needs to pay, the NFR specifies the payment method (e.g. Stripe, PayPal, in-app purchases, etc.).
  • If the user should receive a system email, the NFR says what system will perform it (e.g. MailChimp, Sendinblue, Mailgun).
  • If the user wants to watch a video, NFR determines the player.
  • If the user needs to call, NFT names the video conferencing system to integrate.
  • If the client needs to analyze performance, NFT specifies the requirement for Google Analytics integration.

And so on, so on, so on.

Let’s summarize

To write complete non-functional requirements that can ensure the quality of the system, the analyst better discuss with the client and list the following possible attributes:

  • Localization and Language / Multi-language support,
  • Date and Time formats, Timezone, Currency,
  • Current scale and potential Scalability,
  • Browser support,
  • Operating System / Device compatibility,
  • Quality / Size / Format constraints,
  • Security / Safety / Privacy concerns,
  • Speed (Performance), Responsiveness, Reliability,
  • Third-party integrations.


Functional and non-functional requirements go hand in hand when planning a system. While the first bring more value to the end user, the second explains where and how the product delivers that value. While describing non-functional requirements is crucial for building an MVP, it goes fil-rouge throughout the entire product life cycle.


What Hosting Provider Suits You: AWS vs DigitalOcean vs Hetzner [2023]

CPS logos connected to a server icon with plain lines

Out of dozens cloud hosting providers in Fora Soft we usually consider and build our projects on three: AWS, Digital Ocean, and Hetzner. None of them is universal so in this article we’ll dive deeper into what specific needs and requirements each can cover.

To know the cost of any of the servers listed for your project, use our Server cost calculator. It considers how many streamers and viewers you anticipate, and what quality your streaming service requires.

But first…

What is a cloud service and a cloud service provider (CSP)?

We describe cloud service as any kind of infrastructure that a third-party provider hosts and makes available to users through the internet. Basically cloud services make the process of data delivery from a user’s device to the processing systems easier. 

All it takes for a cloud service to work is software and hardware. Literally like any other IT thing. What makes it different is that a device, connection to the network, and an OS is enough to access cloud services. 

Cloud service providers use their own data centers, physically located processing systems we already mentioned, and host platform services for customer organizations. Now in detail about 3 of them we use.

AWS (Amazon Web Services)

AWS is the world’s most broadly adopted cloud platform with over 200 fully featured services from data centers globally. Basically a market leader. It serves 245 countries, has 27 already existing and 7 servers coming soon, all around the globe, on all continents.

It’s safe to say they offer the broadest set of technical opportunities. Among their clients are fast-growing startups, largest enterprises, and leading government agencies. 

Why does AWS make a great solution

AWS is highly autonomous in its scalability. That means, the system ongoingly monitors changes in the system it hosts, detects the exact moment when it requires scalability and ensures that automatically. 

That results in a smaller chance of system crashing, better performance, and smoother user experience. 

Also what they have to show off is a plethora of IaaS’s (Infrastructure-as-a-Service) and PaaS’s (Platform-as-a-Service). These are ready-made solutions on a pay-as-you go basis. 

Colorful icons in a cloud shape with AWS logo on top
AWS tools

But obviously, such a smart and complex solution costs money. The AWS cost is the highest out of 3 providers we cover in this article. To not waste a pretty penny, it’s better to think twice if your product really needs that kind of scalability opportunities. One of the ways to figure it out is to ask yourself how many users you expect in the first few months. 

In In a nutshell, AWS is a great solution if your company is large and you anticipate hundreds of thousands of concurrent users, or if you need more complex, yet ready-made solutions.


DigitalOcean is another American solution with 14 data centers in total in Asia, Europe, and North America. Their positioning states 3 main principles: keeping it simple, at affordable price, yet high-quality. And they live by that, mostly focusing on developers’ needs. 

Why does DigitalOcean make great solution

Their pricing is one of the most affordable among other providers in general. Still, they show brilliant results in terms of performance. Their network speed is 1Gbps and the start-up time is only 55 seconds. 

As for keeping it simple, DigitalOcean products have neat user-friendly interfaces with one-click deployments. 

DigitalOcean interface and functionality

The downside of DigitalOcean is a not-so-big choice of functionalities and instruments. At least, compared to AWS. That means, in case there’s no suitable tool for your project’s specific requirements, you’ll have to develop your own. 

But after all, the DigitalOcean server cost is almost 7 times less. 

Long story short, DigitalOcean is a great pick if it’s your first release or an MVP and you’re looking for a cheap yet reliable cloud.

Hetzner Cloud

Hetzner Cloud is a German provider with data centers in 4 locations: in Bavaria and Saxony lands in German, in Helsinki, and in the state of Virginia, USA. 

Why does Hetzner Cloud make a great solution

Hetzner Cloud has all the essentials required to start an app, yet they keep prices low and affordable.  

So basically Hetzner, in terms of pricing and effectiveness, is a European alternative to DigitalOcean. As a bonus, it’s not that well known yet, so it’s even cheaper. Perfect for first releases and small startups. 

Since Hetzner locates its data centers mostly in Europe, you might want to consider building on it if you know for sure 90% of your users will be browsing from Europe. Otherwise you can end up losing in speed and overall user experience.

Another con is lack of agileness in choosing servers and tools, same as it is with Digital Ocean. 

Final thoughts

To sum it all up, here’re the essentials to consider when picking a CSP out of 3 listed:

  1. How many users do you expect to use your product at once?
  2. How fast do you plan to grow?
  3. Where are your users browsing from?

And now a quick summary on what each CSP:

You might want to build your product on AWS if you have a very large enterprise, or plan to grow fast.

DigitalOcean is a great pick for you if you’re looking for a low cost, yet reliable media server provider.

Hetzner Cloud will make it even cheaper, yet more suitable for Europe (but not limited by it). 

These are the main providers we work with, but if you have your own favorites or non of them seems to be a match, we can turn to any other CSP.

To calculate your monthly server costs, use our Server cost calculator. And to know the overall price of a project, contact us at or our Head of Sales Vadim on Skype: vadim_prushchik