Seamless multi-master sync, that
- scales from Big Data to Mobile,
- with an IntuitiveHTTP/JSON API
- and designed for Reliability.
Some of the Reviews it gets: –
“Amongst all the panic and horror [of a power outage], I was smiling.”
“The replication in CouchDB is really the killer feature that sets it apart from other databases.”
“Even if the internet was very bad our databases in the two locations would eventually sync.”
Data Where You Need It
Apache CouchDB lets you access your data where you need it. The Couch Replication Protocol is implemented in a variety of projects and products that span every imaginable computing environment from globally distributed server clusters, over mobile phones to web browsers.
Store your data safely, on your own servers, or with any leading cloud provider. Your web- and native applications love CouchDB because it speaks JSON natively and supports binary data for all your data storage needs.
The Couch Replication Protocol lets your data flow seamlessly between server clusters to mobile phones and web browsers, enabling a compelling offline-first user experience while maintaining high performance and strong reliability. CouchDB comes with a developer-friendly query language, and optionally MapReduce for simple, efficient, and comprehensive data retrieval.
Download it through for free and safe:- https://couchdb.apache.org/
Why CouchDB?
Apache CouchDB is one of the new breeds of database management systems. This topic explains why there’s a need for new systems as well as the motivations behind building CouchDB.
As CouchDB developers, we’re naturally very excited to be using CouchDB. In this topic, we’ll share with you the reasons for our enthusiasm. We’ll show you how CouchDB’s schema-free document model is a better fit for common applications, how the built-in query engine is a powerful way to use and process your data, and how CouchDB’s design lends itself to modularization and scalability.
Relax 🙂
If there’s one word to describe CouchDB, it is ‘relax’. It is the byline to CouchDB’s official logo and when you start CouchDB, you see:
Apache CouchDB has started. Time to relax.
Why is relaxation important?
Developer productivity roughly doubled in the last five years. The chief reason for the boost is more powerful tools that are easier to use. Take Ruby on Rails as an example. It is an infinitely complex framework, but it’s easy to get started with. Rails is a success story because of the core design focus on ease of use. This is one reason why CouchDB is relaxing: learning CouchDB and understanding its core concepts should feel natural to almost everybody who has been doing any work on the Web. It is still pretty easy to explain to non-technical people.
Getting out of the way when creative people try to build specialized solutions is in itself a core feature and one thing that CouchDB aims to get right. We found existing tools too cumbersome to work with during development or in production and decided to focus on making CouchDB easy, even a pleasure, to use.
Another area of relaxation for CouchDB users is the production setting. If you have a live-running application, CouchDB again goes out of its way to avoid troubling you. Its internal architecture is fault-tolerant, and failures occur in a controlled environment and are dealt with gracefully. Single problems do not cascade through an entire server system but stay isolated in single requests.
CouchDB’s core
The concepts are simple (yet powerful) and well understood. Operations teams (if you have a team; otherwise, that’s you) do not have to fear random behavior and untraceable errors. If anything should go wrong, you can easily find out what the problem is, but these situations are rare.
CouchDB is also designed to handle varying traffic gracefully. For instance, if a website is experiencing a sudden spike in traffic, CouchDB will generally absorb a lot of concurrent requests without falling over. It may take a little more time for each request, but they all get answered. When the spike is over, CouchDB will work with regular speed again.
The third area of relaxation is growing and shrinking the underlying hardware of your application. This is commonly referred to as scaling. CouchDB enforces a set of limits on the programmer. At first look, CouchDB might seem inflexible, but some features are left out by design for the simple reason that if CouchDB supported them, it would allow a programmer to create applications that couldn’t deal with scaling up or down.
Note:
CouchDB doesn’t let you do things that would get you in trouble later on. This sometimes means you’ll have to unlearn best practices (bad ones) you might have picked up through your current or past work.
A Different Way to Model Your Data
CouchDB will drastically change the way you build document-based applications. CouchDB combines an intuitive document storage model with a powerful query engine in a way that’s so simple you’ll probably be tempted to ask,
“Why has no one built something like this before?”
Django may be built for the Web, but CouchDB is built for the Web. I’ve never seen software that so completely embraces the philosophies behind HTTP. CouchDB makes Django look old-school in the same way that Django makes ASP look outdated.
—Jacob Kaplan-Moss, Django developer
CouchDB’s design borrows heavily from web architecture and the concepts of resources, methods, and representations. It augments this with powerful ways to query, map, combine, and filter your data. Add fault tolerance, extreme scalability, and incremental replication, and CouchDB defines a sweet spot for document databases.
A Better Fit for Common Applications
We write software to improve our lives and the lives of others. Usually, this involves taking some mundane information such as contacts, invoices, or receipts and manipulating it using a computer application. CouchDB is a great fit for common applications like this because it embraces the natural idea of evolving, self-contained documents as the very core of its data model.
Self-Contained Data
An invoice contains all the pertinent information about a single transaction the seller, the buyer, the date, and a list of the items or services sold. As shown in Figure 1. For self-contained documents, there’s no abstract reference on this piece of paper that points to some other piece of paper with the seller’s name and address. Accountants appreciate the simplicity of having everything in one place. And given the choice, programmers appreciate that, too.
Figure 1. Self-contained documents
Yet using references is exactly how we model our data in a relational database! Each invoice is stored in a table as a row that refers to other rows in other tables one row for seller information, one for the buyer, one row for each item billed, and more rows still to describe the item details, manufacturer details, and so on and so forth.
This isn’t meant as a detraction of the relational model, which is widely applicable and extremely useful for a number of reasons. Hopefully, though, it illustrates the point that sometimes your model may not “fit” your data in the way it occurs in the real world.
Let’s take a look at the humble contact database to illustrate a different way of modeling data, one that more closely “fits” its real-world counterpart – a pile of business cards. Much like our invoice example, a business card contains all the important information, right there on the cardstock. We call this “self-contained” data, and it’s an important concept in understanding document databases like CouchDB.
Syntax and Semantics
Most business cards contain roughly the same information – someone’s identity, an affiliation, and some contact information. While the exact form of this information can vary between business cards, the general information being conveyed remains the same, and we’re easily able to recognize it as a business card. In this sense, we can describe a business card as a real-world document.
Jan’s business card might contain a phone number but no fax number, whereas J. Chris’s business card contains both a phone and a fax number. Jan does not have to make his lack of a fax machine explicit by writing something as ridiculous as “Fax: None” on the business card. Instead, simply omitting a fax number implies that he doesn’t have one.
We can see that real-world documents of the same type, such as business cards, tend to be very similar in semantics – the sort of information they carry, but can vary hugely in syntax, or how that information is structured. As human beings, we’re naturally comfortable dealing with this kind of variation.
While a traditional relational database requires you to model your data up front, CouchDB’s schema-free design unburdens you with a powerful way to aggregate your data after the fact, just like we do with real-world documents. We’ll look in-depth at how to design applications with this underlying storage paradigm.
Building Blocks for Larger Systems
CouchDB is a storage system useful on its own. You can build many applications with the tools CouchDB gives you. But CouchDB is designed with a bigger picture in mind. Its components can be used as building blocks that solve storage problems in slightly different ways for larger and more complex systems.
Whether you need a system that’s crazy fast but isn’t too concerned with reliability (think logging), or one that guarantees storage in two or more physically separated locations for reliability, but you’re willing to take a performance hit, CouchDB lets you build these systems.
Explanation
There is a multitude of knobs you could turn to make a system work better in one area, but you’ll affect another area when doing so. One example would be the CAP theorem discussed in Eventual Consistency. To give you an idea of other things that affect storage systems, see Figure 2 and Figure 3.
By reducing latency for a given system (and that is true not only for storage systems), you also affect concurrency and throughput capabilities.
Figure 2. Throughput, latency, or concurrency
Figure 3. Scaling: read requests, write requests or data
When you want to scale out, there are three distinct issues to deal with: scaling read requests, write requests, and data. Orthogonal to all three and to the items shown in Figure 2 and Figure 3 are many more attributes like reliability or simplicity. You can draw many of these graphs that show how different features or attributes pull into different directions and thus shape the system they describe.
CouchDB is very flexible and gives you enough building blocks to create a system shaped to suit your exact problem. That’s not saying that CouchDB can be bent to solve any problem – CouchDB is no silver bullet – but in the area of data storage.
CouchDB Replication
CouchDB replication is one of these building blocks. Its fundamental function is to synchronize two or more CouchDB databases. This may sound simple, but the simplicity is key to allowing replication to solve a number of problems: reliably synchronize databases between multiple machines for redundant data storage; distribute data to a cluster of CouchDB instances that share a subset of the total number of requests that hit the cluster (load balancing); and distribute data between physically distant locations, such as one office in New York and another in Tokyo.
CouchDB replication uses the same REST API all clients use. HTTP is ubiquitous and well understood. Replication works incrementally; that is, if during replication anything goes wrong, like dropping your network connection, it will pick up where it left off the next time it runs. It also only transfers data that is needed to synchronize databases.
A core assumption CouchDB makes is that things can go wrong, like network connection troubles, and it is designed for graceful error recovery instead of assuming all will be well. The replication system’s incremental design shows that best. The ideas behind “things that can go wrong” are embodied in the Fallacies of Distributed Computing:
- The network is reliable.
- Latency is zero.
- Bandwidth is infinite.
- The network is secure.
- Topology doesn’t change.
- There is one administrator.
- Transport cost is zero.
- The network is homogeneous.
Existing tools often try to hide the fact that there is a network and that any or all of the previous conditions don’t exist for a particular system. This usually results in fatal error scenarios when something finally goes wrong. In contrast, CouchDB doesn’t try to hide the network; it just handles errors gracefully and lets you know when actions on your end are required.
Local Data Is King
CouchDB takes quite a few lessons learned from the Web, but there is one thing that could be improved about the Web: latency. Whenever you have to wait for an application to respond or a website to render, you almost always wait for a network connection that isn’t as fast as you want it at that point. Waiting a few seconds instead of milliseconds greatly affects user experience and thus user satisfaction.
What do you do when you are offline?
This happens all the time – your DSL or cable provider has issues, or your iPhone, G1, or Blackberry has no bars, and no connectivity means no way to get to your data.
CouchDB can solve this scenario as well, and this is where scaling is important again. This time it is scaling down. Imagine CouchDB installed on phones and other mobile devices that can synchronize data with centrally hosted CouchDBs when they are on a network. The synchronization is not bound by user interface constraints like sub-second response times. It is easier to tune for high bandwidth and higher latency than for low bandwidth and very low latency. Mobile applications can then use the local CouchDB to fetch data, and since no remote networking is required for that, latency is low by default.
Can you really use CouchDB on a phone? Erlang, CouchDB’s implementation language has been designed to run on embedded devices magnitudes smaller and less powerful than today’s phones.
Document Storage
A CouchDB server hosts named databases, which store documents. Each document is uniquely named in the database, and CouchDB provides a RESTful HTTP API for reading and updating (add, edit, delete) database documents.
Documents are the primary unit of data in CouchDB and consist of any number of fields and attachments. Documents also include metadata that is maintained by the database system. Document fields are uniquely named and contain values of varying types (text, number, boolean, lists, etc), and there is no set limit to text size or element count.
The CouchDB document update model is lockless and optimistic. Document edits are made by client applications loading documents, applying changes, and saving them back to the database. If another client editing the same document saves their changes first, the client gets an edit conflict error on save. To resolve the update conflict, the latest document version can be opened, the edits reapplied and the update tried again.
Single document updates (add, edit, delete) are all or nothing, either succeeding entirely or failing completely. The database never contains partially saved or edited documents.
ACID Properties
The CouchDB file layout and commitment system features all Atomic Consistent Isolated Durable (ACID) properties. On-disk, CouchDB never overwrites committed data or associated structures, ensuring the database file is always in a consistent state. This is a “crash-only” design where the CouchDB server does not go through a shutdown process, it’s simply terminated.
Document updates (add, edit, delete) are serialized, except for binary blobs which are written concurrently. Database readers are never locked out and never have to wait on writers or other readers. Any number of clients can be reading documents without being locked out or interrupted by concurrent updates, even on the same document. CouchDB read operations use a Multi-Version Concurrency Control (MVCC) model where each client sees a consistent snapshot of the database from the beginning to the end of the read operation. This means that CouchDB can guarantee transactional semantics on a per-document basis.
Documents
They are indexed in B-trees by their name (DocID) and a Sequence ID. Each update to a database instance generates a new sequential number. Sequence IDs are used later for incrementally finding changes in a database. These B-tree indexes are updated simultaneously when documents are saved or deleted. The index updates always occur at the end of the file (append-only updates).
Documents have the advantage of data being already conveniently packaged for storage rather than split out across numerous tables and rows in most database systems. When documents are committed to disk, the document fields and metadata are packed into buffers, sequentially one document after another (helpful later for efficient building of views).
When CouchDB documents are updated, all data and associated indexes are flushed to disk and the transactional commit always leaves the database in a completely consistent state. Commits occur in two steps:
- All document data and associated index updates are synchronously flushed to the disk.
- The updated database header is written in two consecutive, identical chunks to make up the first 4k of the file, and then synchronously flushed to disk.
In the event of an OS crash or power failure during step 1, the partially flushed updates are simply forgotten on restart. If such a crash happens during step 2 (committing the header), a surviving copy of the previous identical headers will remain, ensuring coherency of all previously committed data. Excepting the header area, consistency checks or fix-ups after a crash or a power failure are never necessary.
Compaction
Wasted space is recovered by occasional compaction. On schedule, or when the database file exceeds a certain amount of wasted space, the compaction process clones all the active data to a new file and then discards the old file. The database remains completely online the entire time and all updates and reads are allowed to complete successfully. The old database file is deleted only when all the data has been copied and all users transitioned to the new file.
Views
ACID properties only deal with storage and updates, but we also need the ability to show our data in interesting and useful ways. Unlike SQL databases where data must be carefully decomposed into tables, data in CouchDB is stored in semi-structured documents. CouchDB documents are flexible and each has its own implicit structure, which alleviates the most difficult problems and pitfalls of bi-directionally replicating table schemas and their contained data.
But beyond acting as a fancy file server, a simple document model for data storage and sharing is too simple to build real applications on – it simply doesn’t do enough of the things we want and expect. We want to slice and dice and see our data in many different ways. What is needed is a way to filter, organize and report on data that hasn’t been decomposed into tables.
View Model
To address this problem of adding structure back to unstructured and semi-structured data, CouchDB integrates a view model. Views are the method of aggregating and reporting on the documents in a database, and are built on-demand to aggregate, join and report on database documents. Because views are built dynamically and don’t affect the underlying document, you can have as many different view representations of the same data as you like.
View definitions are strictly virtual and only display the documents from the current database instance, making them separate from the data they display and compatible with replication. CouchDB views are defined inside special design documents and can replicate across database instances like regular documents so that not only data replicates in CouchDB, but entire application designs replicate too.
JavaScript View Functions
Views are defined using JavaScript functions acting as the map part in a map-reduce system. A view function takes a CouchDB document as an argument and then does whatever computation it needs to do to determine the data that is to be made available through the view if any. It can add multiple rows to the view based on a single document, or it can add no rows at all.
View Indexes
Views are a dynamic representation of the actual document contents of a database, and CouchDB makes it easy to create useful views of data. But generating a view of a database with hundreds of thousands or millions of documents is time and resource consuming, it’s not something the system should do from scratch each time.
To keep view querying fast, the view engine maintains indexes of its views, and incrementally updates them to reflect changes in the database. CouchDB’s core design is largely optimized around the need for efficient, incremental creation of views and their indexes.
Views and their functions are defined inside special “design” documents. A design document may contain any number of uniquely named view functions. When a user opens a view and its index is automatically updated. All the views in the same design document are indexed as a single group.
The view builder uses the database sequence ID to determine if the view group is fully up-to-date with the database. If not, the view engine examines all database documents (in packed sequential order) changed since the last refresh. Documents are read in the order they occur in the disk file, reducing the frequency and cost of disk head seeks.
The views can be read and queried simultaneously
while also being refreshed. If a client is slowly streaming out the contents of a large view, the same view can be concurrently opened and refreshed for another client without blocking the first client. This is true for any number of simultaneous client readers. Who can read and query the view while the index is concurrently being refreshed for other clients without causing problems for the readers.
As documents are processed by the view engine through your ‘map’ and ‘reduce’ functions. Their previous row values are removed from the view indexes if they exist. If the document is selected by a view function, the function results are inserted into the view as a new row.
When view index changes are written to disk, the updates are always appended at the end of the file, serving to both reduce disk head seek times during disk commits and to ensure crashes and power failures can not cause corruption of indexes.
Security and Validation
To protect who can read and update documents, CouchDB has simple reader access and update validation model that can be extended to implement custom security models.
Administrator Access
CouchDB database instances have administrator accounts. Administrator accounts can create other administrator accounts and update design documents. Design documents are special documents containing view definitions and other special formulas, as well as regular fields and blobs.
Update Validation
As documents are written to disk, they can be validated dynamically by JavaScript functions for both security and data validation. When the document passes all the formula validation criteria, the update is allowed to continue. If the validation fails, the update is aborted and the user client gets an error response.
Both the user’s credentials and the updated document are given as inputs to the validation formula and can be used to implement custom security models by validating a user’s permissions to update a document.
A basic “author only” update document model is trivial to implement, where document updates are validated to check if the user is listed in an “author” field in the existing document. More dynamic models are also possible, like checking a separate user account profile for permission settings.
The update validations are enforced for both live usage and replicated updates, ensuring security and data validation in a shared, distributed system.
Distributed Updates and Replication0
CouchDB is a peer-based distributed database system. It allows users and servers to access and update the same shared data while disconnected. Those changes can then be replicated bi-directionally later.
The CouchDB document storage, view, and security models are designed to work together to make true bi-directional replication efficient and reliable. Both documents and designs can replicate, allowing full database applications (including application design, logic, and data) to be replicated to laptops for offline use, or replicated to servers in remote offices where slow or unreliable connections make sharing data difficult.
The replication process is incremental. At the database level, replication only examines documents updated since the last replication. If replication fails at any step, due to network problems or crashes, for example, the next replication restarts at the last checkpoint.
Partial replicas can be created and maintained. Replication can be filtered by a JavaScript function so that only particular documents or those meeting specific criteria are replicated. This can allow users to take subsets of a large shared database application offline for their own use while maintaining normal interaction with the application and that subset of data.
Conflicts
Conflict detection and management are key issues for any distributed edit system. The CouchDB storage system treats edit conflicts as a common state, not an exceptional one. The conflict handling model is simple and “non-destructive” while preserving single document semantics and allowing for decentralized conflict resolution.
CouchDB allows for any number of conflicting documents to exist simultaneously in the database, with each database instance deterministically deciding which document is the “winner” and which are conflicts. Only the winning document can appear in views, while “losing” conflicts are still accessible and remain in the database until deleted or purged during database compaction. Because conflict documents are still regular documents, they replicate just like regular documents and are subject to the same security and validation rules.
When distributed edit conflicts occur, every database replica sees the same winning revision and each has the opportunity to resolve the conflict. Resolving conflicts can be done manually or, depending on the nature of the data and the conflict, by automated agents. The system makes decentralized conflict resolution possible while maintaining single document database semantics.
Conflict management continues to work even if multiple disconnected users or agents attempt to resolve the same conflicts. If resolved conflicts result in more conflicts, the system accommodates them in the same manner, determining the same winner on each machine and maintaining single document semantics.
Applications
Using just the basic replication model, many traditionally single server database applications can be made distributed with almost no extra work. CouchDB replication is designed to be immediately useful for basic database applications. While also being extendable for more elaborate and full-featured uses.
With very little database work, it is possible to build a distributed document management application with granular security and full revision histories. Updates to documents can be implemented to exploit incremental field and blob replication. Where replicated updates are nearly as efficient and incremental as the actual edit differences (“diffs”).
Implementation
CouchDB is built on the Erlang OTP platform, a functional, concurrent programming language, and development platform. Erlang was developed for real-time telecom applications with an extreme emphasis on reliability and availability.
Both in syntax and semantics, Erlang is very different from conventional programming languages like C or Java. Erlang uses lightweight “processes” and message passing for concurrency, it has no shared state threading and all data is immutable. The robust, concurrent nature of Erlang is ideal for a database server.
CouchDB is designed for lock-free concurrency, in the conceptual model and the actual Erlang implementation. Reducing bottlenecks and avoiding locks keep the entire system working predictably under heavy loads. CouchDB can accommodate many clients replicating changes, opening and updating documents, and querying views whose indexes are simultaneously being refreshed for other clients, without needing locks.
For higher availability and more concurrent users, CouchDB is designed for “shared nothing” clustering. In a “shared nothing” cluster, each machine is independent and replicates data with its cluster mates, allowing individual server failures with zero downtime. And because consistency scans and fix-ups aren’t needed on a restart. If the entire cluster fails – due to a power outage in a data center. For example – the entire CouchDB distributed system becomes immediately available after a restart.
CouchDB is built from the start with a consistent vision of a distributed document database system. Unlike cumbersome attempts to bolt distributed features on top of the same legacy models and databases. It is the result of careful ground-up design, engineering, and integration. The document, view, security, and replication models, the special purpose query language, the efficient and robust disk layout, and the concurrent and reliable nature of the Erlang platform are all carefully integrated for a reliable and efficient system.
x Branch
Want to Contribute?
We welcome your contributions. CouchDB is an open-source project. Everything, from this website to the core of the database itself, has been contributed by helpful individuals. The time and attention of our contributors is our most precious resource, and we always need more of them. Our primary goal is to build a welcoming, supporting, inclusive and diverse community. We abide by the Code of Conduct and a set of Project Bylaws. Come join us!
1.2.1. Version 3.1.2
This is a security release for a low severity vulnerability. Details of the issue will be published one week after this release. See the CVE database for details at a later time.
1.2.2. Version 3.1.1
1.2.2.1. Features and Enhancements
- #3102, #1600, #2877, #2041: When a client disconnects unexpectedly, CouchDB will no longer log a “normal: unknown” error. Bring forth the rainbows.
- #3109: Drilldown parameters for text index searches may now be specified as a list of lists, to avoid having to define this redundantly in a single query. (Some languages don’t have this facility.)
- #3132: The new [chttpd]buffer_response option can be enabled to delay the start of a response until the end has been calculated. This increases memory usage but simplifies client error handling. As it eliminates the possibility that a response may be deliberately terminated midway through, due to a timeout. This config value may be changed at runtime, without impacting any in-flight responses.
1.2.2.2. Performance
1.2.2.3. Bugfixes
- #2935: The replicator now correctly picks jobs to restart during rescheduling, where previously with the high load it may have failed to try to restart crashed jobs.
- #2981: When handling extremely large documents (≥50MB), CouchDB can no longer time out on a gen_server:callif bypassing the IOQ.
- #2941: CouchDB will no longer fail to compact databases if it finds files from a 2.x compaction process (prior to an upgrade) on disk.
- #2955CouchDB now sends the correct CSP header to ensure Fauxton operates correctly with newer browsers.
- #3061, #3080: The couch_indexserver won’t crash and log errors if a design document is deleted while that index is building, or when a doc is added immediately after database creation.
- #3078: CouchDB now checks for and complains correctly about invalid parameters on database creation.
- #3090: CouchDB now correctly encodes URLs correctly when encoding the atts_sincequery string.
- #2953: Some parameters not allowed for text-index queries on the partitioned databases are now properly validated and rejected.
- #3118: Text-based search indexes may now be cleaned up correctly, even if the design document is now invalid.
- #3121: fips now only reported in the welcome message if FIPS mode was enabled at boot (such as in args).
- #3128: Using COPYto copy a document will no longer return a JSON result with two ok
- #3138: Malformed URLs in replication requests or documents will no longer throw an error.
1.2.2.4. Other
- JS tests skip faster now.
- More JS tests ported into elixir: reader_acl, reduce_builtin, reduce_false, rev_stemming, update_documents, view_collation_raw, view_compaction, all the view_multi_keytests, view_sandboxing, view_update_seq.
1.2.3. Ver. 3.1.0
1.2.3.1. Features and Enhancements
- #2648: Authentication via JSON Web Token (JWT). Full documentation is at the friendly link.
- #2770: CouchDB now supports linking against SpiderMonkey 68, the current Mozilla SpiderMonkey ESR release. This provides direct support for packaging on the latest operating system variants, including Ubuntu 20.04 “Focal Fossa.”
- A new Fauxton release is included, with updated dependencies, and a new optional
CouchDB news page.
1.2.3.2. Performance
- #2754: Optimized compactor performance, resulting in a 40% speed improvement when document revisions approach the revs_limit. The fixes also include additional metrics on size tracking during the sort and copy phases, accessible via the:get:`GET /_active_tasks </active_tasks>`
- A big bowl of candy! OK, no, not really. If you got this far…thank you for reading.
For classes of JavaScript, only on- ‘know javascript at the back of your hand website. Your free source of Information and for my other blogs and updates do follow https://topguestposting.com/author/pro-book/